Apache Royale Blog

Royale at ApacheCon 2020

The Apache Software Foundation (ASF) held its annual convention, ApacheCon, September 29-October 1, 2020. Because of the pandemic, it was an all-virtual conference. Participants logged in and attended keynote speeches, track sessions, and informal hallway meetings from all around the world. The conference had a track in Mandarin, and sessions in Hindi.

Attendance broke all previous records, with over three thousand people taking part. Over 80% were attending their first-ever ASF convention.

There were 27 presentation tracks, the largest number ever for ApacheCon. Apache Royale was among them, with presenters in Pakistan, Spain, and Canada.

The tracks were:

  • Hello, Royale!: A high-level tour of what Apache Royale does, its history, and what it offers to people creating new applications or migrating existing Flex applications before the end of Flash support. (Video) (PDF)

  • Moving an App from Flex to Royale: What's involved in migrating a complex, business-critical application from Apache Flex and the Flash platform to Apache Royale. (Video) (PDF)

  • Starting from a blank file: A demonstration of creating a complex application from an empty file, using Royale's existing features and component sets. (Video) (PDF)

  • Tour de Jewel: A review and discussion of the Jewel component set, the most feature-rich of the component sets Royale provides. (Video) (PDF)

You can download and review PDFs of the four presentations or watch the videos of the presentations available on YouTube.

Using Jewel TileHorizontalLayout

This example shows how to use the Jewel TileHorizontalLayout in Jewel components and data-based containers to arrange child elements as tiles. The layout lets you customize the tiles' size, the gaps between tiles, and whether you want them organized by rows or columns.

This layout is modeled very closely on the Apache Flex Spark TileLayout.

Example structure

We're using the Jewel UI set to build a simple interface as a placeholder for the example. We use a Jewel Card in the middle of the screen. Inside the CardPrimaryContent we add a TabBarContent to switch between a Container and a DataContainer both using the TileHorizontalLayout to display child elements as tiles. We switch between the views using a TabBar inside a CardExpandedContent.

Use CardExpandedContent when we need the content adjusted to fit the Card borders without any gap. In our example, we want the TabBar to fill all the available space.

Adding the TabBar

We declare the TabBar using an inline ArrayList as dataProvider with the data to build each TabBarButton.

<j:CardExpandedContent>
    <j:TabBar localId="tabbar" width="100%" selectedIndex="0" sameWidths="true"
       itemRenderer="itemRenderers.TabBarVerticalIconItemRenderer">
        <js:ArrayList>
            <fx:Array>
                <vos:TabBarButtonVO label="Tile Container" hash="sec1" icon="{FontAwesome5IconType.TH_LARGE}"/>
                <vos:TabBarButtonVO label="Tile DataContainer" hash="sec2" icon="{FontAwesome5IconType.TH_LIST}"/>
            </fx:Array>
        </js:ArrayList>
    </j:TabBar>
</j:CardExpandedContent>

The Tabbar add two buttons to control the content that fills all available space (width is 100%). It makes both buttons the same width and puts the focus on the first one (selectedIndex = 0). The TabBarVerticalIconItemRenderer item renderer controls each button's layout. Check the full code to see details on configuring the renderer.

With this code in place we can add the content.

Add the dual TabBarContent

The main content is structured as follows:

<j:CardPrimaryContent>
    <j:TabBarContent selectedContent="{(tabbar.selectedItem as TabBarButtonVO).hash}">
        <j:SectionContent name="sec1">
            <j:Container width="100%">
                <!-- Content to show as tiles-->
            </j:Container>
        </j:SectionContent>
            
        <j:SectionContent name="sec2">
            <j:DataContainer width="100%" height="250">
                <!-- Content to show as tiles-->
            </j:DataContainer>
        </j:SectionContent>

    </j:TabBarContent>
</j:CardPrimaryContent>

The TabBarContent's selectedContent is bound to the TabBar's selectedItem so when a TabBar button is selected the content changes accordingly.

Using the tile layout in a Container

Inside the SectionContent we add a Container configured with TileHorizontalLayout. We can add any content we want to the container, but the size of each piece will be controlled by the layout.

Since no height is provided, no scrolling will be added as the number of content items increases or decreases, and the surrounding card will grow or shrink to adapt to them.

The layout is configured with some horizontal and vertical gaps, and we want three columns by default. This means that the width of the tiles will be calculated to fill all available space, taking into account the requestedColumnCount and the gaps:

<j:Container width="100%">
    <j:beads>
        <j:TileHorizontalLayout localId="thl" verticalGap="6"
            horizontalGap="6" requestedColumnCount="3"/>
    </j:beads>
    
    <html:Div className="box" text="1"/>
    <html:Div className="box" text="2"/>
    <html:Div className="box" text="3"/>
    <html:Div className="box" text="4"/>
    <html:Div className="box" text="5"/>
    <html:Div className="box" text="6"/>
    <html:Div className="box" text="7"/>
    <html:Div className="box" text="8"/>
    <html:Div className="box" text="9"/>
    <html:Div className="box" text="10"/>
    <html:Div className="box" text="11"/>
    <html:Div className="box" text="12"/>

</j:Container>

Using the tile layout in a DataContainer

Inside the SectionContent we add a DataContainer configured with the TileHorizontalLayout. As its name indicates, the content is generated dynamically based on the data in the ArrayList, and the item renderer controls the display of each tile.

You can use other data-based containers like a List if you need more functionality like selection of items, roll-over support or keyboard accessibility.

For this example, we limit the height of the container so the content can be hidden, and add scrolling with the ScrollingViewport bead.

Also we configure columnWidth and rowHeight so the columns will be calculated based on tile size and gaps.

<j:DataContainer width="100%" height="250"
    itemRenderer="itemRenderers.VerticalIconListItemRenderer">
    <j:beads>
        <j:ScrollingViewport/>
        <j:TileHorizontalLayout localId="thll" verticalGap="6"
                horizontalGap="6" columnWidth="130" rowHeight="70"/>
    </j:beads>

    <js:ArrayList>
        <fx:Array>
            <vos:IconListVO label="Ank" icon="{FontAwesome5IconType.ANKH}"/>
            <vos:IconListVO label="Atom" icon="{FontAwesome5IconType.ATOM}"/>
            <vos:IconListVO label="Burn" icon="{FontAwesome5IconType.BURN}"/>
            <vos:IconListVO label="Candy Cane" icon="{FontAwesome5IconType.CANDY_CANE}"/>
            <vos:IconListVO label="Fire" icon="{FontAwesome5IconType.FIRE_ALT}"/>
            <vos:IconListVO label="Duck" icon="{FontAwesome5IconType.DUCK}"/>
            <vos:IconListVO label="Cloud And Moon" icon="{FontAwesome5IconType.CLOUD_MOON}"/>
            <vos:IconListVO label="Europe" icon="{FontAwesome5IconType.GLOBE_EUROPE}"/>
            <vos:IconListVO label="Electric Guitar" icon="{FontAwesome5IconType.GUITAR_ELECTRIC}"/>
            <vos:IconListVO label="Mask" icon="{FontAwesome5IconType.MASK}"/>
            <vos:IconListVO label="Skull" icon="{FontAwesome5IconType.SKULL}"/>
            <vos:IconListVO label="Spider" icon="{FontAwesome5IconType.SPIDER}"/>
        </fx:Array>
    </js:ArrayList>
    
</j:DataContainer>

CardActions to control sizing at runtime

In the example we also add some sliders to control different settings of each layout. For example, to change columnWidth we configure the following slider:

<j:VGroup>
    <j:Label text="columnWidth"/>
    <j:HSlider width="200" value="85" minimum="50" maximum="150" 
            valueChange="tabbar.selectedIndex == 0 ? thl.columnWidth = event.target.value : thll.columnWidth = event.target.value;"/>
</j:VGroup>

We use the tabbar selectedIndex to affect the current selected content layout and avoid changing the content layout in the other tab. Check the final code example to see the rest of sliders since all are similar.

And that's all! I hope you like this layout example in Royale. As always, enjoy coding with Apache Royale!

Where to go from here

The result of this code snippet is the following:

(We're using an iframe to host the actual results of this example compilation. To see the example in a separate window click this link.)

Full project with source code can be found here:

Project Source Code

Apache Royale v0.9.7 released!

The Apache Royale community is pleased to announce the release of Apache Royale 0.9.7.

The Apache Royale project is the next generation of the Apache Flex SDK. It lets developers use MXML and ActionScript 3 to generate HTML/JS/CSS applications which can run natively in browsers. The cross-compiled code can also run on platforms like Electron or Apache Cordova (Adobe PhoneGap) to build mobile applications.

This release should be considered 'beta' quality, although we're very close to a 1.0 release and we have many applications in production at this point. The purpose of this release is to continue to gather feedback about Royale's features and the project's implementation strategies, and to recruit new contributors. We hope to grow the code base into an SDK and tool chain that delivers the highest productivity when developing applications that can run on many platforms. Beta releases, however, may not handle all production needs.

Changes in 0.9.7:

Apache Royale Framework 0.9.7

  • Reflection support improved (supports access to custom namespaces) including improved utility methods
  • Added a getTimer emulation to Core library, similar to flash.utils.getTimer
  • added [RoyaleArrayLike] implementation support to Royale Collections, and BinaryData
  • improvements to XML/E4X conformance, and memory footprint
  • General improvements in Bindings, including function bindings
  • Added new Router classes
  • Added AMFLocalStorage, a javascript version of the Flash runtime LSO (Local Shared Object)
  • Added new ItemRendererInitializer bead infrastructure to decouple better item renderers functionality
  • Added ToolTipRemovalWhenItemRemoved for renderers that use tooltips.
  • Fix bin/mxmlc and bin/compc scripts that did not understand certain default compiler options in royale-config.xml
  • Crux:
    • Improved:
      • Crux can now be used in MXRoyale and SparkRoyale applications
    • New:
      • Added support for using Command pattern to Crux
      • Added Documentation in royale-docs site
  • Graphics:
    • New:
      • Added new high-parity swf graphics emulation (UIGraphicBase)
  • Jewel:
    • Improved:
      • Massive refactors and improvments
      • Hierachy improved in many Jewel framework branches to make StyleUIBase the base of all components and unify APIs.
      • StyleUIBase now improve width and height so we can use NaN values to unset values. For JS this means return to default values.
      • Card: Added new subcomponents (CardHeader, CardTitle, CardPrimaryContent and CardActions)
      • Button: Added new unboxed and outlined styles (also to IconButton and ToggleButton)
      • CheckBox and RadioButton now can size the icon part
      • ComboBox can now confifure custom renders and supports rowCount, and fixed percent width. also popup adapts to data provider length.
      • List supports now variableRowHeight, scrollToIndex and can be navigated with arrow cursors (up/down)
      • Item Renderer: Use the new Initializer infrastructure
      • Remove mappers to rely on basic ones, also remove CRUD beads (Add, Remove and Update item beads)
      • Layouts, Group and Container supports variableRowHeight
      • Layouts many fixes and improvements in alignment, and now dispatch childs dispatch a "sizeChanged"
      • Viewport and ScrollingViewport refactor. Viewport has now clipContent so Container can activate/deactivate
      • added tabindex in many components and to Disabled bead (=-1)
      • Prompt beads now support changes at runtime
      • TabBar: fix AssignTabContent bead when change dataprovider
      • Jewel Themes was updated to show many visual improvements in colors and styles. Flat and Light themes are almost finished. Still Dark themes are work in progress.
      • Tour De Jewel was updated to show all the latest updates
    • New:
      • Runtime Theme Switch. Can be seen working in Tour De Jewel
      • StyledUIBase now adds min and max width and height properties.
      • Added VSlider. The original Slider is now HSlider.
      • Added Paddings bead
      • Added VContainer and HContainer for clipped content
      • Added DataGrid
      • Added ButtonBar
      • Added ComboBoxTrucatedText
      • Added DrawerFooter
      • Added VirtualList and VirtualComboBox to load huge amounts of data in a performant way
      • New colors for text and icons (lightest, light, normal, dark and darkest)
      • Added Jewel TodoMVC and TodoMVC with Crux examples following the TodoMVC website guidelines. Also added more blog examples.
  • Icons
    • Refactored classes IIcon classes to support more icons sets
    • Added FontAwesome v5 support (also v4)
    • Icons now support Material and FontAwesome (more sets can be added)
  • SVG:
    • Fixed SVGImage when using Maven
  • Network:
    • Improved:
      • URLLoader now respects contentType passed in via URLRequest.
    • New:
      • Added URLVariables emulation
  • MXRoyale:
    • Improved:
      • mx.utils.ObjectUtil – improved parity
      • mx.net.SharedObject – improved parity
      • add support for legacy HttpService decoding format
      • Fixes in mx.messaging for polling support, mx.external.ExternalInterface
    • New:
      • mx.net.SharedObjectJSON – new alternative
  • Maven:
    • Massive improvements
    • Now Maven can generate a valid distribution (SDK) to use in any IDE (tested on VSCode and Moonshine) distribution can be JS only
    • SASS generation is now separated from main build to a profile to save lots of time when no need to build themes
  • RoyaleUnit:
    • [Test(async)] may be used to define asynchronous tests
    • [BeforeClass] and [AfterClass] metadata must be added to static methods
    • [Test] metadata supports an 'expected' attribute to expect a thrown exception
    • Fixed incorrect order of expected and actual values in assert messages
  • RoyaleUnitUI: An optional UI to display the results of RoyaleUnit tests
  • Dozens of bugs reported, investigated, and squashed. For details of closed bug reports see GitHub Issues list.

Updates to the RELEASE_NOTES made after this file was packaged into the release artifacts can be found here:

https://github.com/apache/royale-asjs/wiki/Release-Notes-0.9.7

Apache Royale Compiler 0.9.7

  • Definitions containing [JSModule] with a custom module name are no longer required to use strict camelCase naming scheme.
  • Added Flex emulation RPC WebService partial support
  • Fix add event handler code in renderers and inline Components
  • (SWF/JS) Added support for [RoyaleArrayLike] metadata-driven support for proxying compile-time numeric-typed array index access to get/set method calls and also specific for-in/for-each-in loop support.
  • (JS) Compiler updates to support more e4X variations/scenarios, including 'use namespace' and 'default xml namespace' directives
  • (JS) Compiler updates to address custom namespace-related output, and reflection support
  • (JS) Compiler updates to output more compact Reflection data
  • Fixed a compiler memory leak that was occurring over multiple compilations
  • Fixes in bindable code generation for accessors, and in bindable function generation for swf
  • Fixed -show-binding-warnings=false option to switch off binding warnings
  • Maven: Many fixes, improvements and Updates
  • Support for Maven distribution (Create SDK with Maven)
  • (JS) Prevent renaming of public variables in release builds so that they may be set from MXML.
  • (JS) Fix conflict between methods of the same name in superclass and subclass, where the superclass method is private and the subclass method is public.
  • (JS) Added -jsx-factory compiler option to customize the factory method used in code generated from [JSX].
  • (JS) Added -inline-constants compiler option that optionally replaces references to contants with their value when the value is a primitive (like numeric, boolean, or string).
  • (SWF/JS) Added -warn-this-within-closure compiler option that controls whether the compiler emits warnings when referencing this in closures or anonymous functions.
  • (SWF/JS) Added -strict-identifier-names compiler option to make the compiler emit errors when using certain keywords as identifiers, to match the old behavior of the Flex SDK compiler.
  • (SWF/JS) Fix metadata attributes being ignored if they did not have a value. Example: async was ignored in [Test(async)].
  • (SWF/JS) Fix path resolving error when specifying a source file with ./ or .\ on the command line.
  • (SWF/JS) Fix [ArrayElementType] being ignored when setting the [DefaultProperty] in MXML.
  • (SWF) Fix mxmlc and compc scripts in the bin folder that didn't work from the command line.
  • (SWF/JS) Fix incorrect resolving of a property with a different namespace than the parent element in MXML. Properties must have the same namespace as the component, just like in Flex.
  • (SWF/JS) Fix missing error for values that cannot be parsed as text in MXML.
  • (JS) Fix stripped end quotes from strings in data binding expressions in MXML.
  • (Maven) Added missing MXML manifest for core language types like Object, Array, Number, String, Boolean, etc.
  • (JS) Fixed null reference error on source map generation with certain folder hierarchies.
  • (JS) Fixed lost UTF-8 encoding when using remove-circulars.
  • (SWF/JS) Fix missing error when setting private/inaccessible property in MXML.
  • (JS) Fix "missing var keyword" warning from Closure compiler for type definitions.
  • (SWF/JS) Fix missing error for calling a getter as a function (similar to attempting to call a variable as a function) when it is the wrong type.
  • (JS) Fix missing . in generated JS when using static getter/setter in a custom namespace.

For additional information on recent issues that have been closed, see Github Issues List

You can download a binary distribution, the source code or browse our GitHub repositories. If you're a NPM user you can check Apache Royale at NPM.

As well, you can help us filing bug reports for issues you encounter in the framework or compiler.

For questions about how to use Royale, send email to mailto:users@royale.apache.org. For questions and feedback on the development of the source code in the release, send email to dev@royale.apache.org.

Enjoy! 🙂

Newer Posts Older Posts