Apache Royale™ https://royale.apache.org/ News and tutorials about Apache Royale™ Wed, 11 Dec 2024 24:00:00 GMT en-US Apache Royale v0.9.12 released! https://royale.apache.org/blog/apache-royale-v0-9-12-released/ Wed, 11 Dec 2024 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-12-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.12.

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 web browsers. The cross-compiled code can also run on platforms like Electron or Apache Cordova to build desktop or 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.12:

Apache Royale Framework 0.9.12

  • Basic

    • Make shift click aware of the first selection in ListMultiSelectionMouseController.
    • Added ReusableDataItemRendererFactoryForCollectionView for reusable item renderers.
    • Fixed exception in StyleInheritanceWithObserverBead due to attempting to set style inheritance on non-element (e.g. Text) descendant nodes under the strand.
    • ContainerView Checks the type on adding to strand and not on every contentView access
    • Optimized closing tree nodes.
  • Core

    • Added removeDynamicSelector method. Removes a CSS selector dynamically at runtime.
    • Added support for native PointerEvent.
    • Added toDecimals utility method.
    • Fixed "click" not being converted to Royale MouseEvent.
  • Graphics

    • Fixed PathBuilder using out of range radius values when drawing rounded rectangles.
  • Icons

    • Added FontAwesome6IconType with Font Awesome 6 icons.
    • Added new icons to MaterialIconType and FontAwesome5IconType.
  • Jewel

    • Added RestrictRegExp bead, which is essentially a copy of Restrict, but with RegExp property.
    • Added RestrictValidator for validation based on StringValidator capabilities and RegExp pattern.
    • Added ability to dynamically assign itemRenderer to DataGridColumn
    • Added ability to extend and override SnackbarView in Snackbar.
    • Added ComboBoxListWidth bead to set ComboBox List width.
    • Fixed issue in DateChooser where next/previous buttons without text setup property were sized incorrectly.
    • Fixed font size alignment in RadioButton.
  • MXRoyaleBase

    • Added missing mx.messaging.Producer to MXML manifest.
    • Ensure that SecureHTTPChannel, AMFChannel, and SecureAMFChannel are included in SWC.
  • MXRoyale

    • Added event when tool tip changes.
    • Fixed tooltip getting created twice.
    • Fixed Bitmap class for embedding compatibility with Flex.
  • Network

    • Added execute() method to HttpRequestTask.
    • Fixed creation of loader in HttpRequestTask.
    • Fixed BinaryUploader POST data sent to server.
    • Made response headers accessible from URLBinaryLoader and URLStream.
  • XML

    • Improve performance of getting descendants.
    • Added index to XMLList prototype instead of instances to prevent GC thrashing.
  • Fixed broken download locations for playerglobal.swc and Adobe AIR SDK in InstallAdobeSDKs.xml script.

  • Compiler and command line tools now require Java 11 or newer to run.

  • Dozens of bugs reported, investigated, and squashed. For details of closed bug reports see GitHub Issues list.

Apache Royale Compiler 0.9.12

  • compiler: Added new --infer-types compiler option that allows the compiler to automatically detect an appropriate type for both variables and function signatures that have omitted their declared types. Type inference is based on either the initializer or return values.
  • compiler: Abstract classes now support abstract getter and setter methods.
  • compiler: Added --strict-flex-css compiler option to optionally enable CSS syntax limitations that match Flex.
  • compiler: Improved type checking for && and || binary operators and ?: ternary operator.
  • compiler: Removed obsolete "AMD" and "Goog" JavaScript backends, and finished some refactoring to make codebase easier to maintain.
  • compiler: Now requires Java 11 or newer to run. Previously required Java 8 minimum.
  • compiler: Updated various Java dependencies with security updates.
  • compiler: Fixed some Flex SDK integration tests that had been failing for a while.
  • compiler: Fix parsing of <arguments> or <request> properties for RemoteObject, WebService, or HTTPService tags in MXML.
  • compiler: Fix missing warning for duplicate function parameter names.
  • compiler: Fix missing error for multiple root nodes in <fx:Model> tag.
  • compiler: Fix missing errors for invalid MXML manifest files.
  • compiler: Fix null exception when emitting JavaScript if a variable is untyped or function doesn't have a return type
  • compiler: Fix exception for multiple intializers in an MXML field tag.
  • compiler: Fix column position of string inside metadata.
  • compiler: Fix exception when an event attribute in MXML is missing = and quotes.
  • compiler: Fix unnecessary warning when reading SWF data that contains EnableTelemetry tag without a password.
  • compiler: Fix backslash as an escape character for { and } inside MXML data binding.
  • compiler: Fix backslash characters being unescaped in property values when emitting JavaScript.
  • compiler: Fix overflow exception caused by uint values that overflowed an integer in the compiler.
  • compiler: Fix incorrect error or warning positions for CSS content inside <fx:Style> tag.
  • compiler: Fix non-string values in an MXML array sometimes getting incorrectly wrapped in quotes when emitting JavaScript.
  • compiler: Fix null exception for <fx:Style> tags that contain only comments.
  • compiler: Fix exceptions for <fx:Style> tags and defaults.css files that contain invalid CSS.
  • compiler: Fix silently ignoring errors in some invalid CSS content, if it appears at the end after valid content.
  • compiler: Fix crash when attempting to use --remove-circulars=false with a release build.
  • compiler: Added CSS support for modern syntax without commas in rgb and rgba functions.
  • compiler: Added CSS support for radial-gradient, conic-gradient, and repeating gradient functions in JS.
  • compiler: Added CSS support for several translate, rotate, scale, skew, and matrix transformation functions in JS.
  • compiler: Add CSS support for declaring custom properties (CSS variables) and using var function in JS.
  • compiler: Fix crash when [Style] is of type Object and value is passed in MXML.
  • compiler: Fix null pointer exception when omitting quoted <fx:Style> value for source attribute.
  • compiler: Fix null pointer exception when omitting quoted <fx:Binding> value for source, destination, and twoWay attributes.
  • compiler: Fix null pointer exception when omitting quoted <fx:Vector> value for fixed, and type attributes.
  • compiler: Fix missing problem for invalid twoWay value for <fx:Binding> tag.
  • compiler: Fix exception for unexpected attributes added to <fx:Array> and <fx:Vector> tags.
  • compiler: Changed to better problem message when MXML implements attribute is empty.
  • compiler: Fix exception when assigning to a property that has a getter, but not a setter.
  • compiler: Fix exception when working with certain namespace expressions.
  • compiler: Fix configuration problems not being reported when compc options are passed to mxmlc.
  • compiler: Fix source maps for fields and methods in the private namespace or custom namespaces.
  • compiler: Fixed end line and end column of numeric literal with + or - sign.
  • compiler: Fixed lines and columns of function body.
  • compiler: Added support for Friendly Call Frames in source maps.
  • compiler: Fixed missing warning for assignment in else if conditional.
  • compiler: Fixed missing warnings for assignment, return, and comparison of null, undefined, and NaN values with other values that could never possibly be compatible.
  • compiler: Fixed missing errors when calling objects as functions that can never possibly be callable.
  • compiler: Add [RoyaleCallableInstances] metadata to allow instances of a typedef class to be callable as functions. Used by jQuery externs.
  • compiler: Fixed incorrect conflicting definition error when a method in a language namespace (like public/protected) has the same name as a method in a custom namespace.
  • debugger: Fix exception when evaluating certain expressions at run-time.
  • formatter: Added insert-new-line-else configuration option.
  • formatter: Filtered out unnecessary compiler warnings.
  • formatter: Fix stack overflow on some platforms when <fx:Script> code is large enough.
  • formatter: Fix missing indent after empty object literal when collapse-empty-blocks is true (it's not a block).
  • formatter: Fix Unicode and ASCII escape sequences getting lost when formatting string literals.
  • formatter: Fix formatting for configuration constants that gate definitions (like types or fields) without braces.
  • formatter: Fix formatting for object literal inside parentheses.
  • formatter: Fix ignored formatting when file contains unresolved configuration constants.
  • formatter: Fix formatting for comments on same line as control flow that doesn't have braces.
  • formatter: Fix asformat-config.xml file being ignored.
  • formatter: Fix ignored implicit semicolon being formatted as null.
  • formatter: Fix formatting for comment between brace and else.
  • formatter: Fix formatting of unary operators that (depending on context) may also be arithmetic operators.
  • formatter: Fix formatting for switch/case inside for-each or for-in loop.
  • linter: Fix implicit semicolon incorrectly detected as an empty statement that should be removed (it can't be removed).
  • linter: Fix MXML linter being incorrectly used for .as files and AS3 linter being incorrectly used for .mxml files.
  • Building royale-compiler now requires JDK 11 or newer.

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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Apache Royale v0.9.10 released! https://royale.apache.org/blog/apache-royale-v0-9-10-released/ Wed, 31 May 2023 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-10-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.10.

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.10:

Apache Royale Framework 0.9.10

  • RoyaleUnit
    • Added BDD-style expect() method for natural language assertions
    • Added a number of new asserts, including checks for NaN, less than, greater than, less or equal, greater or equal, within range, is of type, throws exception, and matches regular expression.
  • MXRoyale
    • Various bug fixes
  • Jewel
    • Various bug fixes
  • Dozens of bugs reported, investigated, and squashed. For details of closed bug reports see GitHub Issues list.

Apache Royale Compiler 0.9.10

  • aslint is a new command line code linter for ActionScript and MXML, with a programmatic API for use in editors and IDEs.
  • compiler: Added --watch compiler option that keeps compiler active and incrementally compiles when changes to .as and .mxml files are detected. You may exit with Ctrl+C.
  • compiler: Added support for ?? null coalescing operator to ActionScript.
  • compiler: Added support for ?. null conditional operator to ActionScript.
  • compiler: Added support for @"" verbatim strings to ActionScript.
  • compiler: Fix JS output for chained Date setter initialization, like date.minutes = date.seconds = 0.
  • compiler: Fix <![CDATA[]]> handling in MXML for properties with [CollapseWhiteSpace] metadata.
  • royaleunit-ant-tasks: The <royaleunit> Ant Task can now use Playwright to run headless tests in HTML/JS. Set the player to chromium, webkit, or firefox.
  • royaleunit-ant-tasks: Added a new commandArgs attribute to the <royaleunit> Ant Task. It may be used to pass extra command line arguments to the executable specified in the command attribute.
  • formatter: Can load configuration options with -load-config+=path/to/file.xml, similar to compiler.
  • formatter: If a file named asformat-config.xml appears in the current working directory, automatically load it with -load-config. To disable this behavior, use -skip-local-config-file=true.
  • formatter: Fix issue where more than one new line might appear at the end of a file.
  • formatter: Fix indentation between opening and closing parentheses/brackets on separate lines.
  • formatter: Fix detection of Script elements in MXML when line endings are CRLF.
  • formatter: Fix exception when file starts with UTF BOM character.
  • formatter: Fix issue where ternary operator inside if condition was formatted incorrectly.
  • formatter: Fix missing formatting for finally block.
  • formatter: If a case or default clause in a switch contains only a block, indent is not increased.
  • formatter: If formatting is skipped because compiler errors are found, display those compiler errors.

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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Apache Royale v0.9.9 released! https://royale.apache.org/blog/apache-royale-v0-9-9-released/ Wed, 30 Mar 2022 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-9-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.9.

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.9:

Apache Royale Framework 0.9.9

  • MXRoyale
    • MXRoyale has been split 2 libs : MXRoyaleBase (mostly non-UI code) and MXRoyale (mostly UI code). Users of MXRoyale should see no immediate changes as the build of this swc remains the same.
    • Listen to children's resize events to fix some layout issues
    • Various fixes to measured sizes (ComboBox, and other UI components)
    • Fixes to labels in item renderers not displaying correctly
    • ComboBox prompt fixes
    • ArrayCollection.refresh() updating lists
    • Various fixes to labels in item renderers not showing correctly
    • Add option to add custom header renderers to data grids
    • Fix issues with Menu.show() when receiving non-null parent arguments
    • Improve emulation of ADG's expand/collapse behavior
  • SparkRoyale
    • ComboBox sizing improvements
  • Basic
    • Improvements to DragBead's out of bounds behavior
  • RoyaleUnit
    • Fix coercion error in MetadataRunner when expecting an exception in a test, like [Test(expected="RangeError")]
  • Reflection
    • getQualifiedSuperclassName() can find the superclass of a Class object in JS, matching the behavior of SWF
  • Examples
    • Ace example running in Maven
    • Added Jewel TriStateCheckBox example in Tour De Jewel
  • Jewel
    • Improved:
      • Added emphasized and secondary sass settings for Jewel CheckBox / Switch
    • New:
      • Added Jewel TriStateCheckBox and some associated beads: TriStateCheckBoxTooltipState, TriStateCheckBoxState
      • Added ComboBoxReadOnly bead
  • Icons
    • Icon constants have been added to MaterialIconType and FontAwesome5IconType
  • Dozens of bugs reported, investigated, and squashed. For details of closed bug reports see GitHub Issues list.

Apache Royale Compiler 0.9.9

  • asformat is a new command line code formatter for ActionScript and MXML, with a programmatic API for use in editors and IDEs.
  • Added a boolean new compiler option compiler.mxml.force-local-id - (short commandline form force-local-id). This is a quick way to avoid propagating id attributes to browser DOM in JSRoyale.
  • (JS) Added new string compiler options js-getter-prefix and js-setter-prefix to optionally specify different prefixes to use instead of 'get_' and 'set_' for accessors in the generated JavaScript. Useful for integrating with JS libraries/languages that use a different naming convention.
  • (JS) Fix for @royalesuppressexport feature which had stopped working
  • (JS) Fix for mx.managers.SystemManager subclass not being generated for applications that were not direct subclasses of the relevant application classes.
  • (JS) Improvement in output of locale properties files as ResourceBundles. Now using original Flex/SWF parsing approach for improved parity.
  • (JS) First implementation of multiple-catch support in Javascript
  • (JS) Added unsafe option for outputting literal javascript (via externally defined jsUnsafeNativeInline function)
  • Fixed <!----> in MXML being incorrectly detected as an unclosed ASDoc comment, instead of an empty regular comment.
  • (JS) Improved the generated JavaScript for if, else if, and else statements that contained only a semicolon and no braces.
  • (JS) Generated JavaScript for parseInt() passes 0 instead of undefined for radix argument to avoid number format exception.
  • (JS) Fixed several issues with generated JavaScript for E4X expressions when using js-dynamic-access-unknown-members compiler option.
  • (JS) Fixed a couple of issues with generated JavaScript when using custom namespaces.
  • Fixed missing [Event] metadata in playerglobal.swc classes generated from documentation.
  • Fixed parse exception when binding to XML.

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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Apache Royale v0.9.8 released! https://royale.apache.org/blog/apache-royale-v0-9-8-released/ Thu, 02 Sep 2021 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-8-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.8.

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.8:

Apache Royale Framework 0.9.8

  • Core
    • Added getClassStyle function that get an Object with all styles in a CSS className.
  • Basic
    • Move getParentEventTarget() from EventDispatcher to UIBase to reduce require dependencies. This allows EventDispatcher to be used in non-GUI contexts, such as Node.js.
    • UIBase, added loadBeads hook method
    • Added BrowserResizeListener bead that listen for browser resizing and resizes a component accordingly. Old one was renamed to "BrowserResizeApplicationListener"
    • StyledUIBase & ClassSelectorListSupport, added replaceClass method
    • Added ILabelFunction and LabelFunction bead
    • Added LayoutChildren: A bead to trigger layout in children. Added support in StyledLayoutBase.
    • Added interfaces for better extension in Basic and Jewel: IColumns, ITableModel, ITableView, ITextButton, IPaddings, IPositioning
    • Paddings: New bead to add padding in mxml to a component
    • Positioning: New bead to add positioning in mxml to a component
    • Add SelectionDataItemRendererFactoryForCollectionView to handle ISelectionModel for components that uses selection and add/remove/update items at runtime.
  • RoyaleUnit
    • Fixed issue where CIListener incorrectly escaped quotes in messages.
    • Better error messages when [BeforeClass] or [AfterClass] is detected, but method is not found by reflection.
  • Jewel
    • ASDocs: multiple refactors in many components to document and describe better components
    • Item Renderers
      • Refactor to make Basic Layout the default (before was horizontal baked)
      • Initializers now use new Paddings bead. Create a default if no one is found.
      • Remove then minimum height of 34px, so we can have renderers with less height
    • New BinaryImage component
    • Card:
      • New CardExpandedContent: Used for content that needs to avoid paddings like navigation bars
    • Button, CheckBox, RadioButton:
      • add "spanLabel" to separate the text from other decorations like icons and get more control over styling
    • Image added "loadComplete" event
      • New ClipImage bead for images to allow clipping
      • New ErrorImage beads
    • Added SimpleLoader component that show an indeterminate spin circle
    • DataContainer
      • dataProvider is now the DefaultProperty
    • List
      • Added label function through beads
      • New ListAlternateRowColor bead (should be temporal until get nth-child css styles work in compiler)
      • dataProvider is now the DefaultProperty
      • Fixes on SearchFilterForList
    • ComboBox:
      • Fix Sizing issues
      • Improve open popup faster
      • new ComboBoxItemByField bead that allows to select an item by field
      • dataProvider is now the DefaultProperty
      • add item renderer support at mxml (TLC) level
      • Fixes on SearchFilter
    • DateField:
      • Fix Sizing issues
    • TabBar:
      • Multiple refactors to decouple functionality in beads and make renderers more flexible. Now we allow vertical layouts and indicator in renderer can be positiones in different places
      • Add "sameWidths" to make all buttons share the same width.
      • dataProvider is now the DefaultProperty
    • Table
      • Refactor to get better scrolling and fixed header
      • Added label function through beads
      • New TableAlternateRowColor bead
      • Solve RTE when set columns at runtime
      • Added Initializer
      • New TableAlternateRowColor bead (should be temporal until get nth-child css styles work in compiler)
      • Removed CRUD beads and added new CRUDTableItemRendererFactoryForCollectionView
    • DataGrid
      • Multiple fixes in column dimensions to allow more configurations
      • Added sorting through DataGridSortBead
      • Added swap of columns
      • Added label function through beads
      • dataProvider is now the DefaultProperty
      • add item renderer support at mxml (TLC) level
    • PresentationModels refactor for List and DataGrid based controls to allow more flexibility
    • NumericStepper:
      • Fix Sizing Issues
    • New responsive beads: ResponsiveSize, ResponsiveResizeListener and ResponsiveLabelVisibility
    • New TileHorizontalLayout and TileVerticalLayout beads
    • New ViewLayout for View
    • Removed Jewel ControlBar since it was just an HGroup
    • Jewel Themes:
      • Lots of changes to accommodate the rest of component development and fixes in jewel
      • Add fluid text sizing responsiveness, so size of text shrinks or grows depending on device to fit on different screens
    • Start of VirtualDataGrid component (still has some issues)
  • Collections
    • ArrayList.length now is bindable
  • Maven Distribtuon:
    • The distributions built by Maven should now be equivalent to those of the Ant build.
  • Maven Archetypes:
    • updated royale-simple-application-archetype
    • new new royale-jewel-application-archetype
    • new new royale-jewel-module-application-archetype
    • new new royale-jewel-crux-application-archetype
  • 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.8

Apache Royale Compiler 0.9.8

  • Fixed issue where problems in .mxml files were sometimes duplicated.
  • Fixed issue where unrecognized characters in .mxml files were sometimes ignored, and now an error is reported.
  • Fixed some missing syntax checks for bindable variables that should have been the same as non-bindable variables. This may produce some new errors that weren't there before (such as duplicate variable names), but they should have been.
  • Fixed issue where a type annotation referencing a class with a private constructor was not correctly resolved.
  • Improvements/Fixes in Binding support, added support for binding inheritance, similar to Flex.
  • (JS) Source map debugging paths of SDK classes are updated to allow breakpoints in the original .as or .mxml files in the SDK when debugging in a browser or IDE.
  • (JS) Added source-map-source-root compiler option to optionally customize the source root of source maps.
  • (JS) No longer generates @export annotations for exported symbols in debug builds. Exports are smartly generated when creating a release build, and if they are disabled, they will be omitted from framework classes now too. This can help reduce the size of a release build.
  • (JS) Fixed issue where compiling a .swc library with another .swc library on the library-path did not copy the required .js files to the new .swc library. Only when a .swc library is added external-library-path should the .js files not get copied.
  • (JS) Improved reproducible builds of .swc library files by ensuring that the paths to .js.map source map files are always referenced with forward slash and never backslash. This matches the existing behavior of references to .js files included with .swc libraries.
  • (JS) Static getters/setters are not accessed with ["name"] syntax in generated JavaScript anymore, which required them to always be exported, even if the associated export symbols compiler option were disabled.
  • (JS) When internal namespace is used in ActionScript, the generated JavaScript adds the @package annotation.
  • (JS) Fixed issue where the Language class was not loaded in the correct order when type coersion is required in a static initializer.
  • (JS) (Advanced) Added export-internal-symbols and prevent-rename-internal-symbols compiler options to match the existing options for public and protected namespaces.
  • (JS) (Advanced) Added prevent-rename-public-static-methods, prevent-rename-public-instance-methods, prevent-rename-public-static-variables, prevent-rename-public-instance-variables, prevent-rename-public-static-accessors, and prevent-rename-public-instance-accessors compiler options to provide more granular control when prevent-rename-public-symbols is true (same for protected and internal namespaces too).

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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Royale at ApacheCon 2020 https://royale.apache.org/blog/royale-at-apachecon-2020/ Fri, 02 Oct 2020 24:00:00 GMT https://royale.apache.org/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 https://royale.apache.org/blog/using-jewel-tilehorizontallayout/ Tue, 11 Aug 2020 24:00:00 GMT https://royale.apache.org/blog/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! https://royale.apache.org/blog/apache-royale-v0-9-7-released/ Fri, 15 May 2020 24:00:00 GMT https://royale.apache.org/blog/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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Working with vector graphics https://royale.apache.org/blog/working-with-vector-graphics/ Sun, 29 Mar 2020 24:00:00 GMT https://royale.apache.org/blog/working-with-vector-graphics/ This example shows some ways you can work with vector graphics in Apache Royale. Since Royale draws in part from the sources of Flash and Flex technologies, you'll find that the powerful Flash drawing API is supported for JavaScript and SWF applications. On the other hand, Apache Royale also supports use of SVG graphics.

In this example we create an Erlenmeyer flask, a measuring and mixing container for laboratories, that we can fill with some kind of strange green fluid. We can change the level of the fill with a Jewel HSlider, and use a ToggleButton to show or hide an indicator of the maximum level the liquid can reach. The bottle is be a static SVG shape and the fluid is drawn at runtime as the code responds when the slider value changes.

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; the Jewel HorizontalCenteredLayout centers the card in the card on both axes.

As usual, the Card has three sections: a CardHeader (with the title), a CardPrimaryContent (that holds the bottle) and a CardActions (with some controls).

This is the main structure:

<j:Card width="460" height="680">
    <j:CardHeader>
        <html:H3 text="Working with vector graphics" className="primary-normal"/>
    </j:CardHeader>
    <j:CardPrimaryContent itemsHorizontalAlign="itemsCentered">

        <!-- Here will have the bottle -->

    </j:CardPrimaryContent>
    <j:CardActions itemsHorizontalAlign="itemsRight" itemsVerticalAlign="itemsCentered">
        <j:BarSection width="50%">

            <!-- Here will go the ToggleButton -->

        </j:BarSection>
        <j:BarSection width="50%" itemsHorizontalAlign="itemsRight">

            <!-- Here will go the Slider -->

        </j:BarSection>
    </j:CardActions>
</j:Card>

With this code in place we can…

Create the bottle

We use SVG graphics to assemble the flask, and ActionScript 3 code using the powerful Flash drawing API to create and manage the liquid. We're using both to show you both options so you have more weapons in your arsenal.

For the flask, I created three SVG files using a design tool. You can use whatever tool you prefer to draw vector art and export it in SVG format. I used Affinity Designer software to create it since I think it's one of the best professional and modern tools available today. But many other free, open source and commercial options are available, so choose whatever you want.

The flask's three files are: A mask, a shade (with some reflections and gradients) and the main flask shape. I loaded the files with the svg:Image Royale component. Then I added a red indicator line coded In SVG directly in Royale to show that option with svg:Rect. Finally the fluid uses the UIGraphicsBase class that lets you work with the Flash drawing API.

I added all the parts to a Jewel Container so I can position them in relation to each other as layers. The Container clips the content so things that fall outside the container boundaries are hidden.

You can see all the pieces in perspective in the following image:

Here is the final code of the Container that composes all the graphic parts:

<j:Container localId="fgShape" width="400" height="500">
    
    <!-- liquid -->    
    <js:UIGraphicsBase localId="bgShape" width="400" height="500"/>
    
    <!-- rule -->
    <j:Group>
        <svg:Rect localId="rule" x="180" y="{bgShape.height - rule.height}" width="6" height="350">
            <svg:fill>
                <js:SolidColor color="#ff0000" alpha=".5"/>
            </svg:fill>
        </svg:Rect>
    </j:Group>
    <!-- fill mask -->
    <svg:Image src="assets/bottle-mask.svg" width="400" height="500"/>
    <!-- inner shade -->
    <svg:Image src="assets/bottle-shade.svg" width="400" height="500"/>
    <!-- main shape -->
    <svg:Image src="assets/bottle-main.svg" width="400" height="500"/>

</j:Container>

Notice that the fluid is declared first so the other shapes can hide the fluid that is outside the flask shape.

Fluid controls

To provide some interactivity we add a ToogleButton and an HSlider. The button lets you show and hide the indicator line; move the slider to change the fluid level from empty to full.

The ToogleButton has the following code:

<j:ToggleButton localId="ruleVisibility" 
    outlined="true" emphasis="emphasized"
    text="Hide Rule" selectedText="Show Rule" selected="true">
    <j:icon>
        <js:ToggleFontIcon text="{MaterialIconType.VISIBILITY_OFF}" selectedText="{MaterialIconType.VISIBILITY}" material="true"/>
    </j:icon>
</j:ToggleButton>

It uses an outlined style with emphasized coloring, and material icons and texts for both selected and unselected states.

Show and Hide the indicator with binding

We control the visibility of the red indicator line with the data binding Royale feature:

First add ApplicationDataBinding to the application beads to make Royale support binding at that level (Remember that Royale is PAYG, so we only add code when it is really necessary instead of adding lots of code that you probably will never use to every component).

Then add the binding to the Group that holds the rule.

<!-- rule -->
<j:Group visible="{ruleVisibility.selected}">

When you run the application, click the button to show and hide the red indicator.

Add the slider

We finish the action controls part by adding a label and a slider in the last BarSection of the CardActions. The slider lets you change the fluid level.

<j:Label text="Slide to fill"/>
<j:HSlider localId="slider" value="0" minimum="0" maximum="500"/>

Drawing the fluid

Using the drawing API in Royale is easy, and well-supported by both JavaScript and SWF. We get the Graphics instance of the UIGraphicsBase object in the following way:

var g:Graphics = Graphics.getInstanceFor(bgShape);

Now we can use the graphics object to invoke drawing functions like moveTo, lineTo, and more.

To draw the fluid we use the following function using fills, lines and quadratic bezier curves:

/**
 * Draw the liquid to fill the bottle
 */
private function drawLiquid(g:Graphics, color:Number, alpha:Number, x:int, y:int, width:int, height:int, wave:int):void {
    if(y > height)
        y = height;
    g.beginFill(color, alpha);
    g.moveTo(x, height);
    g.lineTo(x, y);
    g.curveTo(width / 4, y - wave, width / 2, y);
    g.lineTo(width / 2, y)
    g.curveTo(width * 3 / 4, y + wave, width, y);
    g.lineTo(width, height);
    g.lineTo(x, height);
    g.endFill();
}

Then to join all the pieces we add a valueChange event handler to the HSlider:

<j:HSlider localId="slider" value="0" minimum="0" maximum="500" valueChange="changeFill(event)"/>

The changeFill function is the following:

/**
 * Fill the bottle
 */
private function changeFill(event:ValueChangeEvent):void {
    var g:Graphics = Graphics.getInstanceFor(bgShape);
    var newHeight:Number = transformValueFromRange(slider.value, slider.minimum, slider.maximum, 0, rule.height);
    var newY:Number = fgShape.height - newHeight;
    
    g.clear();
    drawLiquid(g, liquidColor, .5, 0, newY, 400, 500, -15);
    drawLiquid(g, liquidColor, 1,  0, newY, 400, 500, 30);
}

When we change the HSlider position, the code calls the function, gets the graphic object, calculates the new height value based on the current container height (transforming ranges), clears all drawings and redraws two different liquids with some displacement on X and change on the wave length with the new values.

And that's all! I hope you like this drawing feature in Royale. You'll be able to do many creative things in your Royale applications with it!

As always, enjoy!

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

]]>
How to create a Desktop Application with Royale and Electron https://royale.apache.org/blog/how-to-create-a-desktop-application-with-royale-and-electron/ Thu, 26 Mar 2020 24:00:00 GMT https://royale.apache.org/blog/how-to-create-a-desktop-application-with-royale-and-electron/ With Apache Royale and Electron you can publish your projects to desktop applications. In this guide you'll learn how to do that.

The short version is to create an Electron project, create an Apache Royale project inside of that and then point the Electron app to the generated Apache Royale html page. You then communicate through the ipcRenderer. We'll be using Visual Studio Code for this guide. The complete example project is attached at the end.

Prerequisites:

  • Install Visual Studio Code – Link
  • Install ActionScript & MXML plugin (required – also included in the extension pack below)Link
  • Install npm (required)Link
  • Install Apache Royale SDK (required)Link
  • Install Electron plugin – Link
  • Install Firefox Debugger plugin – Link
  • Install Git – Link
  • Extension pack that includes AS3 & MXML plugin, AS3 projects and AS3 snippets – Link

Create an Electron project

A basic Electron application needs just these files:

  • package.json – This points to the app's main file and lists its details and dependencies.
  • main.js – Starts the app and creates a browser window to render HTML. This is the app's main process.
  • index.html – A web page to render. This is the app's renderer process.

You also need a reference to an Electron development instance. This can be in the form of a /node_modules directory in your project or a reference to another external location. We will show two ways to reference it.

Creating a New Project

Visual Studio Code doesn't have a New Project menu option that you might be used to from using Flash Builder or other IDEs. Some extensions will set up new projects for you.

Instead you create a folder and define configuration files in the folder. Visual Studio Code then looks for those settings and uses them to set up the environment and provide code intelligence.

Open Visual Studio Code (if it is open already, create a new instance with Command + Shift + N or Control + Shift + N) and then click on Open Folder.

Create a new folder named "Electron-Royale", select it and then click Open.

A new Explorer section opens.

New Visual Studio Project (showing Welcome screen)

On the right side of the screen (or left) you see the Explorer section. Under that you the "Electron-Royale" area. That is our project folder.

In the heading are the New File, New Folder, Refresh and Collapse buttons. They appear when you hover the mouse pointer over the header area.

Project Folder

Open files appear in the Open Editors view:

Open Editors area

If the Welcome screen is still open, click the X button to close it.

For an Electron app we create this folder structure:

your-app/
├── package.json
├── main.js
└── index.html

If you haven't created an Electron app before, read this short overview page and then return here.

There are extensions that can create the project for us but we're going to do it by hand for this guide. Why? You will be editing these options frequently until the project is set up.

Create the package.json in the root directory by clicking the New File button and adding the following:

{
   "name": "electron-royale-app",
   "version": "1.0.0",
   "description": "Electron and Royale",
   "main": "main.js",
   "scripts": {
      "start": "electron ."
   },
   "devDependencies": {
      "electron": "^5.0.1"
   }
}

You could also create the package.json project by using the npm init command.

Open a new Terminal window (built in to Visual Studio Code):

New Terminal Window

In the Window that opens enter the following command and follow the prompts:

npm init

You can simply press enter multiple times and type the values into the editor afterwards:

Prompts from npm init

Type yes to confirm. Visual Studio creates a new package.json file in the root directory. A few of the values will be different, so set them back to the values we have above.

Now we create the main Electron js file main.js. Note: There are other examples that use index.js instead.

Click the New File button and name the file main.js:

Main js

Again, read this overview page if you are new to Electron, and then return here.

Enter the following for main.js:

const { app, BrowserWindow } = require('electron')

// Keep a global reference of the window object. If you don't, the window will
// close automatically when the JavaScript object is garbage collected.
let win

function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  // and load the index.html of the app.
  win.loadFile('index.html')

  // Open the DevTools.
  //win.webContents.openDevTools()

  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

Note: Some code may be affected by the copy and paste process. If any code is encoded into HTML entities then you will see an error. Simply convert them back to the greater than or less than characters. Use the example project at the end for comparison.

We then need to create an HTML page to display in our Electron app.

Click the New File button, name it index.html and then enter the following value:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using node <script>document.write(process.versions.node)</script>,
    Chrome <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>
</html>

We have one last step before running our project. We need the Electron node_modules folder (or a reference to it).

We can install this folder locally to our project or, if we've installed the Electron plugin, we can use that.

Let's use the extension first and then do it manually after.

Install the Electron plugin above and then click the Debug button that runs along the edge of Visual Studio Code. When you click it, it opens the Debug view:

Here you can launch different tasks, including debugging your application.

Click the No configurations dropdown list and you'll see Add Configuration. Click that.

Add Configuration option

This will show a list of options, including one called Electron. Select this option.

Electron Launch Configuration

When you select Electron from the dropdown list, a launch.json file is created and placed in a .vscode folder in the root of your project, and the launch.json file opens in an editor tab.

Launch Configuration

You can see the configuration is a simple JSON string like our other configurations.

Let's update the name to Launch Electron and save the document. You can see the name updated in the Debug view:

Launch Electron button

Now, to launch your first Electron app you can use npm start from the Terminal view, or you can click the Launch button in the Debug view. For this guide use the Launch button.

If everything went correctly your first Electron app appears. Congratulations!

Hello World in Electron

Shortly after opening it it will show the Chrome dev tools:

Dev tools

You can use the Dev tools to set breakpoints, inspect the page elements and more.

Let's prevent the dev tools from opening for now. You can re-enable them later.

Open main.js and find and comment out or remove the line below, then save the document:

win.webContents.openDevTools();

When you're debugging a session in Visual Studio Code a debug bar appears:

Debug bar appearing

Use that to Pause, Continue, Step Over, Step Into, Step Out of, Reload or Stop your app. You can dock this bar through an option in the VSC preferences… Code > Preferences > Settings > Tool bar location > docked.

Install Electron in the Project

We can set up Electron manually as well, and in this case we install it inside the project folder.

The reason to install it in the project is so we can switch between different versions and maintain control of our dependencies. The downside is that the project has to download an Electron instance and each project instance will take up additional space. If you work on a project on a team it's recommended to keep the instance in your project but not to commit it into version control.

Note: We can have Electron installed inside our project and use the electron install from the Electron plugin or reference another instance externally. Our launch configurations will allow that.

We are going to install Electron in to our root project directory.

Close the app if it is open by going to the menu and choosing Quit your-app.

Quit menu

Open the built in Terminal and enter the following npm command:

npm install --save-dev electron

Electron will begin downloading the node_modules and its progress will show in the Terminal view:

Downloading…

Download Complete

When the download is complete you see a new folder in your project called node_modules:

Node installed locally

You will also see that npm install creates a package-lock.json file.

The file package-lock.json is like a quick save for your project. Using it, you or your teammates can restore the dependencies to a specific versioned state. It's described more here, here and here. Commit this configuration instead of the node_modules directory when using version control.

Once the Node modules have been downloaded we may need to manually create the .vscode directory and the launch.json configuration. Create the .vscode directory and launch.json file and enter the value below:

{
   "version": "0.2.0",
   "configurations": [
      {
         "name": "Debug Main Electron Process",
         "type": "node",
         "request": "launch",
         "cwd": "${workspaceRoot}",
         "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
         "windows": {
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
         },
         "args" : ["."],
         "outputCapture": "std"
      }
   ]
}

Since the launch.json already exists we can add our new configuration settings to it.

BTW notice in the launch configuration above that the type is node and that runtimeExecutable options are defined.

Let's add our new manual configuration next to our existing extension-created configuration. Open launch.json config and use the values below:

{
   "version": "0.2.0",
   "configurations": [
      {
         "type": "electron",
         "request": "launch",
         "name": "Launch Electron",
         "appDir": "${workspaceFolder}"
      },
      {
         "name": "Debug Main Electron Process",
         "type": "node",
         "request": "launch",
         "cwd": "${workspaceRoot}",
         "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
         "windows": {
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
         },
         "args" : ["."],
         "outputCapture": "std"
      }
   ]
}

You'll see why we have added both later.

I recommend you read about the Electron Architecture here and then continue.

You can read more here:

  • Electron Quick Start – link
  • Electron Quick Start project – link
  • Your first Electron project – link
  • Electron Architecture – link

Create an Apache Royale project

Now we are going to create our Apache Royale project.

Make sure you have the AS3 & MXML extension installed as mentioned above. This requires Java 1.8. An install page is listed here.

Once the extension is installed you need to point to the Apache Royale SDK in the project. We will do it manually and you can see how to have the extension do it at the link provided earlier.

Open the Explorer view and open the .vscode directory.

In that directory create a settings.json file:

Apache Royale SDK settings.json

Enter the following text:

{
   "as3mxml.sdk.framework": "/Users/user/Documents/Royale_SDK/apache-royale-0.9.4-bin-js/royale-asjs"
}

That will not work as is. You need to enter the path to the directory where you downloaded and installed the Apache Royale SDK.

There is a more in-depth guide here that shows how to set up the SDK with the help of the AS3 & Flex extension. You can use the information to confirm the SDK is available to your project.

Once the SDK is set up you'll need to add an asconfig.json to your project. The asconfig.json file is used to add code intelligence to AS3 and MXML files.

Open the Explorer view, select the root project directory, and create a new file with the New File button. Name it asconfig.json.

asconfig in project directory

Open the asconfig.json file and enter the following:

{
   "compilerOptions": {
      "source-map": true,
      "html-template": "index.html",
      "theme": "${royalelib}/themes/JewelTheme/src/main/resources/defaults.css"
   },
   "additionalOptions": "-warn-public-vars=false",
   "files":
   [
      "src/HelloWorld.mxml"
   ]
}

Notice the page we are pointing to in the html-template option. This is the Electron index.html page. We will use this as the Royale app template page.

Note: We can use any page as a template but we need to update the page with special tokens that the Apache Royale compiler looks for.

Note: In the theme option we have a token for royalelib. If you have any issues with this, if the components do not look like they have any theme, then you may have to use the full path to your Royale install.

For example, you may have to use something like:

"C:/ApacheFlexInstall/apache-royale-0.9.6-bin-js-swf/royale-asjs/frameworks/themes/JewelTheme/src/main/resources/defaults.css"

Note: We can add another configuration option called config that will provide us with code intelligence for the node APIs (see first line).

{
   "config": "node",
   "compilerOptions": {
      "source-map": true,
      "html-template": "index.html",
      "theme": "${royalelib}/themes/JewelTheme/src/main/resources/defaults.css"
   },
   "additionalOptions": "-warn-public-vars=false",
   "files":
   [
      "src/HelloWorld.mxml"
   ]
}

This shows us classes and code completion for some Node APIs (possibly only for the Main process). The issue when we use this option is we get an error on the first line of our MXML document:

This tag could not be resolved to an ActionScript class. It will be ignored. js:Application

You can have this option enabled and choose to Debug anyway and it will run. For now, remove this option and add it in later if appropriate as needed.

Let's continue and update our HTML page to our HTML template.

Open the index.html page in the root of the project directory and enter the following HTML:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="Custom Template for injecting custom style CSS">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="${application}.css">
    <link href="//fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet">
${head}
</head>
<body>
${body}
</body>
</html>

Notice we have the ${head} and ${body} tokens.

Now we need to create a new directory for our application.

In the root of the project create a directory named src and create an MXML document in that directory named HelloWorld.mxml.

HelloWorld.mxml

In HelloWorld.mxml enter the following value:

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
   xmlns:js="library://ns.apache.org/royale/express" 
   xmlns:html="library://ns.apache.org/royale/html" 
   xmlns:j="library://ns.apache.org/royale/jewel">
   <js:initialView>
      <js:View>
         <js:Label id="helloLabel" text="Hello World" x="240" y="20"/>
         <j:Button id="helloButton" text="Hello" x="20" y="20"/>
      </js:View>
   </js:initialView>
</js:Application>

Create the Compile Task

To compile our Royale application we need to create a compile task. We can use the AS3 & MXML extension to create a compile task or we can do it manually.

Let's create a compile task manually and then maybe later create it with the extension.

In the .vscode directory create a tasks.json:

Tasks

In tasks.json add the following value:

{
   "version": "2.0.0",
   "tasks": [
      {
         "label": "Compile",    
         "type": "actionscript",
         "debug": true,
         "group": {
            "kind": "build",
            "isDefault": true
         }
      }
   ]
}

For documentation about the tasks.json format go here.

Notice the label property. It is named Compile. We can name it anything, but for now name it Compile. We'll refer to this task later by name as a preLaunchTask.

Before we can launch our Apache Royale app we need to build it. Building it compiles the MXML and ActionScript into HTML and JS.

We can build it from the Run Build Task in the Visual Studio Code menu.

In the menu go to Terminal and choose Run Build Task.

Run Build Task

You can also use Command + Shift + B or CTRL + Shift + B.

That will open Terminal and show you messages from the Apache Royale compiler. Check these messages for any errors and information about the project.

When that is complete you'll see a "compile successful" message:

Compile Successful

Congratulations! You will also see a new directory in your project named /bin:

Exported to bin directory

We could open this index page in a browser using the Firefox debugger, but for our Electron app we are not done yet.

If we launched our Electron app now, not the Royale app, it would open the template page because it is still pointing to the index page in the root of our project.

Pointing to the template

The actual Royale application is in bin/js-debug/index.html that is created after we compile HelloWorld.mxml. So we need our Electron app to load in the application page and not the template.

Open main.js and find the line that loads in index.html:

// load the index.html of the app.
win.loadFile('index.html')

Change it to point to our exported Royale application:

// load the Apache Royale index.html
win.loadFile('bin/js-debug/index.html')

Note: We can easily load in different pages in Electron using the loadFile() method. You can use inter-process communication to have an action on your web page load another web page. You'll learn more about this later.

If you've compiled the Royale project successfully and changed the path to load the index.html page in the bin directory, we are ready to start our Electron project.

Open the Debug view and start Launch Electron. Since everything always goes well on the first try you should have a running application:

Royale Hello World

Note: If you the button is missing its theme, check the theme value in the asconfig.json and troubleshoot as mentioned above.

Note: If we make changes to our application and then run the Launch Electron task again we may not see our changes.

In Flash Builder there was an option to Build Automatically that was enabled by default. What this means is your projects were built automatically when you saved the document. Building the application also provided warnings and error messages in the problems view. We can do something similar with a prelaunch task.

Let's add a prelaunch task to build our application before we launch it.

Remember how we named our compile task earlier? We are are going to tell our Electron launch configuration to run the Royale compile task before starting the application.

Open launch.json and add a prelaunch task property and set it to our Compile build task (mentioned in the tasks.json file). The launch.json should look like the following:

{
   "version": "0.2.0",
   "configurations": [
      {
         "name": "Launch Electron",
         "type": "electron",
         "request": "launch",
         "preLaunchTask": "Compile",
         "appDir": "${workspaceFolder}"
      },
      {
         "name": "Debug Main Electron Process",
         "type": "node",
         "request": "launch",
         "cwd": "${workspaceRoot}",
         "preLaunchTask": "Compile",
         "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
         "windows": {
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
         },
         "args" : ["."],
         "outputCapture": "std"
      }
   ]
}

Make sure the name is the same. It is case sensitive. We can, of course, add more launch configurations with or without these options at any time.

FYI You can learn about the possible launch attributes and their values by hovering your mouse pointer over them or by going here.

Now launch the application again using either of the two launch configurations.

You'll see that the Royale application is built right before the Electron application is launched. If there are any errors in your Royale app the Electron app will not launch.

Communicating with the Main Process

Electron apps have two primary processes. The Main process and the Renderer process. The Royale application runs in the Renderer process and the Electron application runs in the Main process.

Although the processes are separate you can communicate between them using a variety of methods. Read more about this here and then continue.

For this guide we'll send messages.

Open your "Hello World" mxml application and add a script block below the js Application tag and above the initialView tag:

<fx:Script>
    <![CDATA[

    public function clickHandler(event:Event):void {
        var electron:Object;
        var ipcRenderer:Object;

        // check for electron
        // if we add tag config:"node" to our asconfig we get node code intelligence but error for js:Appliction
        if (window["require"]) {
          electron = window["require"]("electron");
          ipcRenderer = electron.ipcRenderer;
          ipcRenderer.send("mainMessageHandler", "hello");
          ipcRenderer.on("rendererMessageHandler", rendererMessageHandler)
        }
        else {
          helloLabel.text = "Electron is not found";
        }
    }

    public function rendererMessageHandler(event:Object, data:String):void {
        trace("Data received:", data);
        helloLabel.text = data;
    }

    ]]>
</fx:Script>

In the button add a click handler:

<j:Button id="helloButton" text="Hello" x="20" y="20" click="clickHandler(event)"/>

When we are running in an Electron app the Renderer process, or the browser window, makes additional objects available. The main ones are electron and ipcRenderer. We will use these for communication.

Sending a message is somewhat like dispatching an event. We can send synchronous and asynchronous messages.

The following example code will dispatch a "sayHello" message with a "hello" value:

// example code
const electron = window["require"]("electron");
const ipcRenderer = electron.ipcRenderer;

ipcRenderer.send("sayHello", "hello");

We are sending a String but we could send an Object. Read more here before continuing.

In our main.js we will add a listener to handle this event. At the end of the main.js document add the following:

const { ipcMain } = require('electron')
ipcMain.on("mainMessageHandler", (event, arg) => {
  console.log(arg);
  var time = new Date().toLocaleTimeString();
  win.webContents.send("rendererMessageHandler", "hello there. it's " + time);
})

Notice the rendererMessageHandler. We have added a listener for this event in HelloWorld.mxml.

Launch the application and click the Hello World button.

Hello World message

Debugging

To debug the Renderer process, HelloWorld.mxml, add a breakpoint in the button click handler. Open the debug view and click Launch Electron. When you click the Hello button, the debugger opens at that point showing you local variables and classes. Take a minute and review the objects available to your application:

Debug Hello World

To debug the Main process, main.js, add a breakpoint in the mainMessageHandler. Open the debug view and click Debug main Electron process.

Debug Main

We use the first one to debug the Renderer process and the second to debug the Main process. You can also use the integrated Chrome dev tools mentioned earlier.

Chrome dev tools

Open launch.json. In the first launch configuration notice the type says electron. In the second launch configuration notice the type is node.

Note: This author has not found a way to hit both breakpoints for the Royale application and the Electron app in one session in Visual Studio Code. However, using a combination of the integrated Chrome dev tools (shown above) to set breakpoints you can use the second configuration, Debug main Electron process, to break on both the Royale and Electron processes, but the break occurs in the Chrome Dev tools and not Visual Studio Code. You could also debug the Royale instance only using the Firefox debugger and launching in a browser.

Summary

In this guide you've created a desktop application using Royale and Electron. You've sent a message to the Main process and sent that message back to the Renderer process. You've set a break point in the debugger.

The example project is attached here: Apache Royale Electron zip

If you use the Moonshine IDE, an example project is available here.

Next Steps

  • The Wiki has more information on the AS3 & MXML plugin here
  • Electron documentation here and here
  • Sample Electron apps here
  • ipcMain and ipcRenderer
  • Apache Royale Getting Started here
  • Install the Firefox Debugger and debug Royale in the browser
  • Electron Hello World Walkthrough on YouTube here
  • Learn the Apache Royale components and layouts with Tour of Jewel here
  • Join the Apache Royale Mailing Lists

Contributions

Thanks to the work of numerous individuals and projects in the Apache Royale community.

]]>
Apache Royale v0.9.6 released! https://royale.apache.org/blog/apache-royale-v0-9-6-released/ Tue, 08 Oct 2019 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-6-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.6.

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.6:

Apache Royale Docs

  • We have restructured and largely rewritten the online documentation. It now contains reference pages for components and code, and links to Apache Royale (ASDoc) references to help new users get up to speed with Royale. Check it out here.

Apache Royale Framework 0.9.6

  • Compiles faster.
  • For applications targeting JavaScript, you can now incorporate the vast resources available in existing, free JavaScript libraries.
  • Many additional components are available:
    • for the Jewel component set, Wizard, PopUp, TabBar, Module, ModuleLoader, FooterBar, Badge, ScrollableSectionContent, and HorizontalListScroll are now available.
  • Emulations of many other components are available.
  • Many improvements and fixes in the Jewel component set:
    • Full implementation of DateField/DateChooser.
    • Components now work correctly on IE11 and on Android/iOS mobile devices.
    • Many improvements to all themes, such as styles for new components and a disabled style that was missing in some components.
    • Many beads have been added for Jewel components:
      • Search filter bead for Jewel ComboBox
      • SearchFilterForList bead to use with Jewel List and TextInput
      • RequiredSelection for DropDownList
    • Improvements to how your application handles focus.
    • Button now extends from the new BasicButton.
  • Many improvements to the Tour De Jewel demo app to show components and beads introduced in this version.
  • Added BrowserOrientation bead.
  • Added loadCSS, to load external CSS dynamically.
  • Added generation of source-maps to all Royale libs for better debugging of framework code.
  • Added new RoyaleUnit library for unit testing.
  • Improvements to AMF / RemoteObject Support.
  • AMFBinaryData api now matches flash.utils.ByteArray (one missing feature is support for non-UTF String encoding). It therefore now works for deep cloning via readObject/writeObject and registerClassAlias.
  • Updates to the Royale collections library with support for sorting and filtering via ArrayListView. Simple example added to Tour de Jewel.
  • A conforming runtime implementation of AS3 Vector (typed Arrays) was added for JavaScript output, with options for avoiding certain runtime checks.
  • int, uint, and Class are now represented as simple, distinct types (Class is now not an 'Object' and int is now not a 'Number', for example), and these support indirect 'as' or 'is' type checking and instantiation, matching swf behavior.
  • General improvements and additions to the Reflection library.
  • A new Apache Royale Crux MVC/DI/IOC application architecture library (based on the Swiz framework that was popular in Flex development) was added, with some simple examples.
  • Added and updated documentation in many areas of the ASDoc reference.
  • Dozens of bugs reported, investigated, and squashed. For details of closed bug reports see GitHub Issues list.

Apache Royale Compiler 0.9.6

  • Added -allow-abstract-classes compiler option to enable abstract keyword for classes and methods.
  • Added -allow-private-constructors compiler option to enable classes with private constructors.
  • Added -allow-import-aliases compiler option to enable import-renaming syntax.
  • Added -verbose compiler option to reduce console output by default.
  • Added RoyaleUnit tasks for Apache Ant.
  • Fixed incorrect compiler error when unicodeRange value is specified for Embed metadata.
  • Fixed missing compiler error when adding type parameters to classes other the Vector.
  • Fixed missing compiler error for instantiation of a variable with new that is not typed as Class or Function.
  • Fixed missing compiler warning for missing types on function parameter.
  • Fixed internal cache that broke IDEs that use the compiler to provide code intelligence.
  • Fixed automatic type coercion in generated JavaScript so that it better matches SWF behavior.

Updates to the RELEASE_NOTES made after this file was packaged into the release artifacts can be found at this link. You can see more here.

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:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Dividing an Apache Royale application with modules https://royale.apache.org/blog/dividing-an-apache-royale-application-with-modules/ Wed, 26 Jun 2019 24:00:00 GMT https://royale.apache.org/blog/dividing-an-apache-royale-application-with-modules/ This example shows how you can break an Apache Royale application into parts called Modules. You then have a main application that acts as a shell for the modules, that hold key features or functions, and that are loaded on demand, not when the user first opens the application.

In this way you benefit from better load times for your application since you don't load all the code at once. Another benefit is better compile times, since you have to build the application or module to which you have made changes, so you compile less code.

The application uses a ModuleLoader to load each module as it is needed. ModuleLoader can load a module directly (this is the default behavior), or you can turn off automatic loading by setting autoLoad to false, and perform the load of each module on demand.

This example shows a Jewel Card with a ModuleLoader and a button that triggers the load. You can push the button and see the sample Module load.

The Main Application

This is the code for the main application that holds the ModuleLoader:

<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html">

    <fx:Script>
        <![CDATA[
           public function loadModule():void
           {
               moduleLoader.loadModule();
           }
        ]]>
    </fx:Script>
    
    <j:beads>
        <js:ApplicationDataBinding />
    </j:beads>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:HorizontalCenteredLayout/>
            </j:beads>

            <j:Card percentWidth="90">
                <html:H3 text="Dividing an Apache Royale application with modules"/>
                
                <j:Label html="This example uses Modules to load parts of the application"/>

                <j:ModuleLoader localId="moduleLoader" autoLoad="false"
                               modulePath="modules" moduleName="JewelModule"/>

                <j:Button text="Load a Module" emphasis="primary" click="loadModule()"/>
             </j:Card>
        </j:View>
    </j:initialView>
</j:Application>

As you can see, the ModuleLoader needs to know the modulePath (the path where the module can be found) and the moduleName (the name of the module to load). We set autoLoad to false to avoid having the module load when ModuleLoader is added to the application. The module loads when a user pushes the button that calls moduleLoader.loadModule(). That's all!

The Sample Module

This is the code for the Module:

<j:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:j="library://ns.apache.org/royale/jewel"
        xmlns:js="library://ns.apache.org/royale/basic"
        initComplete="initModule()">
    
    <fx:Script>
        <![CDATA[
            private function initModule():void
            {
                trace("Initialize the module!");
            }
        ]]>
    </fx:Script>

    <j:beads>
        <js:ContainerDataBinding/>
        <j:VerticalLayout/>
    </j:beads>
    
    <j:valuesImpl>
        <js:SimpleCSSValuesImpl/>
    </j:valuesImpl>
    
    <j:HGroup gap="3">
        <j:IconTextInput>
            <j:beads>
                <j:TextPrompt prompt="Search..."/>
                <j:SizeControl size="xlarge"/>
            </j:beads>
            <j:icon>
                <js:FontIcon text="{MaterialIconType.SEARCH}" material="true"/>
            </j:icon>
        </j:IconTextInput>
        <j:Button text="Search" emphasis="secondary">
            <j:beads>
                <j:SizeControl size="xlarge"/>
            </j:beads>
        </j:Button>
    </j:HGroup>
    
</j:Module>

We need to use the Module tag as the main tag. This means that the module can't be loaded on its own. It needs to be parented by an application and loaded by a ModuleLoader.

The content of the module can be whatever code you want. In this case we are adding just a few Jewel controls to show a big search box.

Notice that the module has an initComplete handler where you can execute code you need to initialize the module (in this case just a log a message). This is similar to the applicationComplete feature for the application itself.

Since this particular module uses a search icon that comes from MaterialIconType, when you add it directly to an application, the compiler injects a link to make Material Icons available. Since this class is used in a module, not in the application itself, Royale adds it via JavaScript to the html head when the module is loaded, so it is ready to be added to the application.

Project structure

We have multiple compilation units (one application and one or more modules), building this application is more complex than a simpler application. You used to have a project for the application and a project for the module. You would like to copy the module output files into the target application folder to make the module available for the compiled application. In this example, Maven helps you by providing a maven build layout for an application and its modules and copying the files you need to the right folders for both debug and release compilations. Check the project source code below.

A simpler option is to have only one project with application and modules all together. This is how Tour De Flex is done. For this layout you must use module-output compiler option so royale can output modules in the folder you prefer. Check Apache Royale Modules documentation page to know more about it.

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

]]>
Using external JavaScript libraries in Apache Royale https://royale.apache.org/blog/using-external-javascript-libraries-in-apache-royale/ Mon, 03 Jun 2019 24:00:00 GMT https://royale.apache.org/blog/using-external-javascript-libraries-in-apache-royale/ This example shows how to use external JavaScript libraries in your Apache Royale application. You can add quick functionality to your application by including code that is not part of Apache Royale itself or is even not written in ActionScript.

In this way, you get lots of libraries available for free in the Internet to strengthen and extend your Apache Royale Application.

It also allows an IDE to provide code completion, type checking, etc.

The example shows a Jewel Card with a code text zone that loads an ActionScript code example. Click the "highlight block" button to show the code in a beautifully colored way, thanks to processing by a highlight library which is an external JavaScript library.

The JavaScript library used to show this feature is highlightjs. In JavaScript this library creates the hljs object our code references.

How to use JavaScript external libraries

We have two solutions available for using external JavaScript libraries in Apache Royale. We'll focus first on the better and recommended way, which is using the @externs compiler directive.

This method gives you robust access to JavaScript methods though ActionScript with dot access syntax (and lets you use code hinting in your IDE). But if you need to prototype something quickly, you can use dynamic syntax with bracket access notation.

Dot access

This is the recommended way. You get all advantages of an object-oriented language like ActionScript 3: type checking, compiler errors and warnings, and code hinting and code completion in your favorite IDEs.

The code for this hljs as3 stub code is located in this blog example project and is the @externs class definition for hljs:

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      //www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package
{
    /**
     * @externs
     */
    COMPILE::JS
    public class hljs
    {
        /** 
         * <inject_script>
         * var script = document.createElement("script");
         * script.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js");
         * document.head.appendChild(script);
         * var link = document.createElement("link");
         * link.setAttribute("rel", "stylesheet");
         * link.setAttribute("type", "text/css");
         * link.setAttribute("href", "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css");
         * document.head.appendChild(link);
         * </inject_script>
         */
        public function hljs(){}

        public static function highlightBlock(block:Element):void {}
    }
}

You can see two main things in this code:

  1. An inject_html directive declared in the constructor adds the following lines to the html template, so you do not need to add the lines manually. If you use this library, Royale adds these references automatically, and if you remove all references, Royale removes the dependencies to the JavaScript library and nothing is output in the html file.
  2. Use the highlightBlock static function, which you can access as a normal method in the AS3 hljs class.

Bracket access

If you need to prototype something quickly you can use this method but remember we don't recommend that you use this in your main Apache Royale project.

First, reference the JavaScript library (and/or css if it exists) in your html template. For hljs you can copy the following lines:

<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<link rel="stylesheet" title="Atom One Dark" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

Then you can start using the library in your code. An example with the highlightjs hljs object is:

var hljs:Object = window["hljs"];
hljs["highlightBlock"](block);

As you can see, this avoids using a more structured language like ActionScript 3. You lose type checking and the compiler will not help you if you write something wrong. Plus, if the API is changed, that code will not be able to warn you about the changes.

The example

The example uses HTTPService to retrieve sample code and display it in an html:Code component. When the application loads, it fires the initialize event. We use that to order HTTPService to load the text file. When the file finishes loading, HTTPService fires a complete event. We use that to add the text file content to the code_txt String variable.

Note: Since the code_txt variable uses data binding (it's marked with the Bindable metadata and we prepared the application to handle data binding with the ApplicationDataBinding bead), the application fills the html:Code sourceCodeMXMLText with the loaded text.

This is the code for this example:

<?xml version="1.0" encoding="UTF-8"?>
<!--

 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

-->
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html"
              initialize="codeTextLoader.send();">

    <fx:Script>
        <![CDATA[
           [Bindable]
           public var code_txt:String;

           public function highLightContent():void
           {
                COMPILE::JS
                {
                    hljs.highlightBlock(sourceCodeMXMLText.element);   
                }
           }
        ]]>
    </fx:Script>
    
    <j:beads>
        <js:ApplicationDataBinding/>
        <js:HTTPService id="codeTextLoader" url="as3code.txt" complete="code_txt = codeTextLoader.data;"/>
    </j:beads>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:HorizontalCenteredLayout/>
            </j:beads>

            <j:Card width="90%">
                <html:H3 text="Using external JavaScript Libraries"/>
                
                <j:Label html="This example uses hljs library to highligh a piece of code"/>

                <html:Pre height="300" width="100%" style="background-color: white">
                    <html:beads>
                        <j:ScrollingViewport/>
                    </html:beads>
                    <html:Code id="sourceCodeMXMLText" text="{code_txt}"/>
                </html:Pre>
                
                <j:Button text="highlight Block" emphasis="primary" click="highLightContent()"/>
             </j:Card>
        </j:View>
    </j:initialView>
</j:Application>

In the example code you can see how we call the hljs.highlightBlock method with the recommended dot syntax as with any other ActionScript code, creating a seamless integration between your project code and the external JavaScript code.

Conclusion

You can see how simple and elegant it can be to use external JS code, while not compromising the safe syntax you have when using the MXML and AS3 languages, to give you more dynamic options for your application at no cost.

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.4 released! https://royale.apache.org/blog/apache-royale-v0-9-4-released/ Mon, 10 Dec 2018 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-4-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.4.

The Apache Royale project is a continuation of the previous effort called FlexJS to produce a next-generation of the Apache Flex SDK that enables developers to use MXML and ActionScript to generate HTML/JS/CSS applications which can run natively in browsers. The cross-compiled code can also be used in Apache Cordova (Adobe PhoneGap) mobile applications.

This release should be considered 'beta' quality. The purpose of this release is to gather feedback about the features and implementation strategies, and to recruit new contributors. We hope to grow the code base into an SDK and tool chain that deliver the highest productivity when developing applications that can run on many platforms. Beta releases may not handle production needs.

In 0.9.4 you can find important additions like a full new UI set called Jewel that's ready for production. This new set was designed with look and feel / themes in mind, so you can have a cool interface out of the box just using Jewel. Another great addition is bringing full AMF/RemoteObject support to Apache Royale so you can ease your migration from Apache Flex.

We are also working hard on MX and Spark emulation components that will help make your migration of an existing Apache Flex application a breeze. Many people are contributing to this effort, but more are welcome: please help us develop this powerful feature.

Changes in 0.9.4:

Known Issues:

  • Users only using Basic components and not MXRoyale or SparkRoyale emulation components should delete frameworks/libs/MXRoyale.swc, frameworks/libs/SparkRoyale.swc, frameworks/js/libs/MXRoyaleJS.swc, and frameworks/js/libs/SparkRoyaleJS.swc from their library paths (or from the file system).

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

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

You can see more here.

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 bugs in the framework or compiler.

For questions about how to use Royale, send email to mailto:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Hello Node: How to transpile ActionScript 3 for Node.js https://royale.apache.org/blog/hello-node-how-to-transpile-actionscript-for-node-js/ Wed, 03 Oct 2018 24:00:00 GMT https://royale.apache.org/blog/hello-node-how-to-transpile-actionscript-for-node-js/

Note: This tutorial was originally published in Josh Tynjala's NextGen ActionScript website, but is now donated to Apache Royale. The tutorial has been adapted to correct the things that changed in Apache Royale since it was published.

Over the years, many developers have dreamed of using ActionScript on both the client and the server. Today, the Apache Royale™ SDK finally makes it possible.

Apache Royale and Node.js logos

Let's learn to use asnodec to write ActionScript code that runs in the popular server-side JavaScript environment, Node.js.

Screenshot of Node.js console output running in the terminal

With asnodec, we'll get full access to all Node.js APIs, and it's even possible to require npm modules in ActionScript. We'll start with a simple example.

Requirements

For this tutorial, you should install Node.js. The newest Long Term Support (LTS) release is recommended.

Additionally, you will need Apache Royale 0.9.4 or newer. Use the downloads page, or download it from Node Package Manager with

npm install -g @apache-royale/royale-js

Create a new project

  1. Create a new, empty folder for your project, and name it HelloNode.
  2. Inside the new project, create a new folder named src. This is where our ActionScript classes will go.
  3. Inside the src folder, create a file named HelloNode.as, and add the following code:
package
{
    public class HelloNode
    {
        public function HelloNode()
        {
            console.log("Hello", process.release.name, process.version);
            dns.lookup("localhost", null, dnsLookupCallback);
        }

        private function dnsLookupCallback(error:Object, address:String):void
        {
            console.log("The address of localhost is:", address);
        }
    }
}

In this class, we're doing two things. First, we're printing the version of Node to the console. Then, we're using Node's built-in dns module to look up an IP address.

It is not necessary to call require() for built-in Node modules in ActionScript. The compiler will detect when a module is used, and it will generate the appropriate call to require() automatically when generating the final JavaScript. (require() is necessary for custom modules)

Compile the project on the command line

Inside the Apache Royale SDK, the js/bin folder contains several different exeuctables used to transpile ActionScript to JavaScript.

What do each of those executables in js/bin do?

  • asjsc compiles pure ActionScript to JavaScript with access to web browser APIs like the HTML DOM.
  • asnodec compiles pure ActionScript to JavaScript with access to Node.js APIs to create server-side or command line projects. We'll use this one.
  • mxmlc compiles applications that use the Apache Royale framework components.

Use the asnodec executable to transpile the HelloNode ActionScript class that you created above for Node.js.

asnodec src/HelloNode.as

This will produce a folder named bin containing js-debug and js-release folders. The js-debug folder contains JavaScript that is easy to read, and each class is loaded at runtime from a separate file. The js-release folder contains JavaScript that has been concatenated and minified for production.

The project should now contain the following files and folders:

Screenshot of project files, including bin/js-debug, bin/js-release, and src/HelloNode.as

Finally, let's try running our code with Node.js.

Run the project

Inside the js-debug folder, a file named index.js will be created as the entry point for your Node.js project. You can run this script using the node executable:

node bin/js-debug/index.js

You should see the following output in your console:

Hello node v6.11.0
The address of localhost is: 127.0.0.1

(The Node version number might be different, obviously!)

What's Next?

This is just a simple example, but it gives you a glimpse of how developers can bring ActionScript server-side using Apache Royale and Node.js. By using an established ecosystem like Node.js, ActionScript developers can take advantage of all of the libraries published to NPM and join a large, vibrant community.

]]>
Loading external data through HTTPService https://royale.apache.org/blog/loading-external-data-through-httpservice/ Sun, 23 Sep 2018 24:00:00 GMT https://royale.apache.org/blog/loading-external-data-through-httpservice/ This example shows you how to use HTTPService to access external data to use in your Apache Royale application.

You can use HTTPService to retrieve data in XML, JSON, or other formats. We'll use GitHub API services to get JSON formatted GitHub data so we can load info about the code of this example, which is hosted in GitHub.

It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.

<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html"
              xmlns:services="services.*">

    <fx:Script>
        <![CDATA[
           import org.apache.royale.events.Event;
           import org.apache.royale.events.MouseEvent;
           import org.apache.royale.jewel.Alert;

           public function getGithubContent(event:MouseEvent):void
           {
               service.getContent();
           }
           
           public function dataReadyHandler(event:Event):void
            {
               Alert.show(service.jsonToString, "JSON data retrieved");
               jsonData.html = "Some JSON Data: <br><strong> - service.json.name:</strong> " + service.json.name + 
                                "<br><strong> - service.json.sha:</strong> " + service.json.sha +
                                "<br><strong> - service.json._links.html</strong> " + service.json._links.html;
                sourceCodeMXMLText.text =  service.sourceCode;
            }
        ]]>
    </fx:Script>
    
    <fx:Declarations>
        <services:GitHubService id="service" 
           sourceCodeUrl="https://api.github.com/repos/apache/royale-asjs/contents/examples/blog/BE0011_Loading_external_data_through_HTTPService/src/main/royale/BE0011_Loading_external_data_through_HTTPService.mxml"
           dataReady="dataReadyHandler(event)"/> 
    </fx:Declarations>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:HorizontalCenteredLayout/>
            </j:beads>

            <j:Card percentWidth="90">
                <html:H3 text="Loading Github external data through HTTPService"/>
                
                <j:Label text="This example loads its source code in the text code panel:"/>

                 <html:Pre height="300" percentWidth="100" style="background-color: white">
                    <html:beads>
                        <j:ScrollingViewport/>
                    </html:beads>
                    <html:Code id="sourceCodeMXMLText"/>
                </html:Pre>
                
                <j:Label id="jsonData" multiline="true" html="This label shows JSON data when loaded."/>

                <j:Button text="Retrieve source code from Github" emphasis="primary" click="getGithubContent(event)"/>
             </j:Card>
        </j:View>
    </j:initialView>
</j:Application>

We create an Apache Royale interface that shows a text code panel to load the source code of this example in it. GitHub doesn't let us load a page from its domain in an iFrame, so this is the only way to embed GitHub content in your application.

The text code panel is made of pre and code html tags with some custom style to make the background white. We provide a Label to show accessing Json data directly with dot notation. Finally we provide a button to trigger the HTTPService.

Tip: We use the ScrollingViewport bead to add scrolling behavior to our text code panel.

The most important piece in this example is the custom GitHubService class that wraps the HTTPService object. We declare it in MXML in our application to pass the Github URL to request and declare an event handler to show the data once it is loaded.

This is the GitHubService class:

package services
{
    import org.apache.royale.events.Event;
    import org.apache.royale.events.EventDispatcher;
    import org.apache.royale.net.HTTPConstants;
    import org.apache.royale.net.HTTPService;
    import org.apache.royale.utils.string.Base64;

    [Event(name="dataReady", type="org.apache.royale.events.Event")]
    /**
     * GitHubService is in charge of getting the source code of some example
     * so we can show the code in a TabBarContentPanel along with the working example
     */
    public class GitHubService extends EventDispatcher
    {
        /**
         * constructor
         */
        public function GitHubService():void
        {    
            service = new HTTPService();
            service.addEventListener(HTTPConstants.COMPLETE, completeHandler);
        }

        /**
         * the service that performs the request to Github
         */
        private var service:HTTPService;

        /**
         * we dispatch an event once we have the source code from github
         */
        private function completeHandler(event:Event):void
        {
            dispatchEvent(new Event("dataReady"));
        }

        private var _sourceCodeUrl:String = null;
        /**
         * The source code url we want to retrieve
         */
        public function get sourceCodeUrl():String
        {
            return _sourceCodeUrl;
        }
        public function set sourceCodeUrl(value:String):void
        {
            _sourceCodeUrl = value;
            service.url = sourceCodeUrl;
        }

        /**
         * json returns the retrieved GitHub JSON Object
         */
        public function get json():Object
        {
            return service.json;
        }

        /**
         * jsonToString returns the retrieved GitHub JSON Object as String
         */
        public function get jsonToString():String
        {
            return service.data;
        }

        /**
         * decode and return the base 64 content (real source code)
         */
        public function get sourceCode():String
        {
            return Base64.decode(service.json.content);
        }
        
        /**
         * trigger the HTTPService to retrieve the GitHub data
         */
        public function getContent():void
        {
            service.send();
        }
    }
}

We instantiate the HTTPService in the constructor, and declare an event listener for the HTTPConstants.COMPLETE event, so we perform actions when the data finishes loading. The action we do from this class is throw a new event "dataReady" to consume in our application.

sourceCodeUrl will pass the GitHub url to be called by our service class, and fills HTTPService.url so HTTPService knows what url to target.

As we get the data loaded, we can manage it with HTTPService.data, and we have a convenient HTTPService.json getter to access the JSON Object that HTTPService already parses for us. We exposed this data in our json class as jsonToString and json getters respectively.

Finally, the source code is in the json.content variable, but comes encoded in base64, so we can use Apache Royale's decode function in the Base64 class to get the decoded xml string to use in our example App. We exposed this in a convenient getter function in our service called sourceCode.

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

]]>
Customization through the Royale API https://royale.apache.org/blog/customization-through-the-royale-api/ Wed, 01 Aug 2018 24:00:00 GMT https://royale.apache.org/blog/customization-through-the-royale-api/ This example shows you how to use the powerful Royale API to get access to the internal workings of components and customize them to suit your needs. As you can see, although Royale does a lot for you to simplify development, you always have full control of your code.

It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.

<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html"
              xmlns:models="models.*">

    <fx:Script>
        <![CDATA[
            import org.apache.royale.core.IBeadLayout;
            import org.apache.royale.core.IBeadView;
            import org.apache.royale.events.CloseEvent;
            import org.apache.royale.events.Event;
            import org.apache.royale.events.MouseEvent;
            import org.apache.royale.jewel.Alert;
            import org.apache.royale.jewel.CheckBox;
            import org.apache.royale.jewel.beads.layouts.HorizontalLayout;
            import org.apache.royale.jewel.beads.layouts.VerticalLayout;
            import org.apache.royale.jewel.beads.views.AlertView;

           private var alert:Alert;
           private var check:CheckBox;

           // Adding content to the Alert component and changing the ControlBar's Buttons Layout
           private function clickHandler(event:MouseEvent):void {
               alert = Alert.show("This example shows access to AlertView and ControlBar to add a CheckBox to the Alert's content area, expand the Button layout and change its defaults. The height of the alert is changed to 300px, too.", "Customized Alert Example", 3);
               alert.addEventListener(CloseEvent.CLOSE, alertClickHandler);
                alert.height = 300;

               check = new CheckBox();
               check.selected = true;
               check.text = "Buttons must fill the ControlBar's available space";
               check.addEventListener(Event.CHANGE, expandButtons);

               expandButtons();
           }
           
           private function expandButtons(event:Event = null):void {
               var alertView:AlertView = alert.getBeadByType(IBeadView) as AlertView;

               if(event == null)
               {
                   var verticalLayout:VerticalLayout = new VerticalLayout();
                   verticalLayout.gap = 9;
                   alertView.content.addBead(verticalLayout);

                   alertView.content.addElement(check);
               }

               var layout:HorizontalLayout = alertView.controlBar.getBeadByType(IBeadLayout) as HorizontalLayout;
               layout.itemsExpand = check.selected;
           }

           // Event handler function for displaying the selected Alert button.
           private function alertClickHandler(event:CloseEvent):void {
               alert.removeEventListener(CloseEvent.CLOSE, alertClickHandler);

               if (event.detail == Alert.YES)
                   status.text="You answered Yes";
               else
                   status.text="You answered No";
           }
        ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:HorizontalCenteredLayout/>
            </j:beads>

            <j:Card width="350">
                <html:H3 text="Customization through Royale API"/>
                
                <j:Label text="This is a complex example that adds and retrieves beads at runtime. Click the button below to display an Alert window that adds content and makes changes in some parts of the default layout."
                       multiline="true"/>
                <j:Button text="Click Me" click="clickHandler(event)"/>
                <j:Label id="status"/>
            </j:Card>
        </j:View>
    </j:initialView>

</j:Application>

This example takes the Using the Jewel Alert Control example and uses the Royale API to add content and customize some parts of the Alert.

The code is more complex than in some of our other examples, for teaching purposes:

  • In the clickHandler method, we create an Alert control and create a CheckBox to add to the Alert's content zone. Then we call the expandButtons method to end initial customization.
  • The expandButtons method is where the heavy work of the Royale API happens:
    • Since all components in Royale are "composed" through the Strand/Bead API, we want to access the view part of the Alert; in this case we're talking about AlertView.
    • We can access AlertView with getBeadByType that retrieves a bead by its type.
    • Then, for learning purposes, we create a VerticalLayout bead and add it to the Alert's content using the addBead method (you can investigate other methods in the API like removeBead as well).
    • We add the CheckBox created in the previous method to the Alert's content. Since this involves a call-back method and an initialization method, we only want to add the checkbox at initialization time and not each time the user clicks the CheckBox.
    • Finally, we retrieve the ControlBar's default HorizontalLayout and customize it to expand its items (the buttons) to fill all the available space in the control bar. We use getBeadByType again to reference the layout, and then use a method available in most Jewel Layouts called itemsExpand that expect a Boolean. When this method is set to "true" all items in the layout expand to use all available space.

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

]]>
Using an Item Renderer with a List https://royale.apache.org/blog/using-an-item-renderer-with-a-list/ Fri, 13 Jul 2018 24:00:00 GMT https://royale.apache.org/blog/using-an-item-renderer-with-a-list/ This example shows how to use an ItemRenderer to display the items in a List in your Royale application. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html"
              xmlns:models="models.*">

    <fx:Style>
        @namespace "http://www.w3.org/1999/xhtml";
        @namespace j "library://ns.apache.org/royale/jewel";

        .iconListItemRenderer
        {
            IItemRenderer: ClassReference("itemRenderers.IconListItemRenderer");
        }
        .iconListItemRenderer .fonticon
        {
            margin-right: 24px;
        }
    </fx:Style>

    <j:model>
        <models:ListsModel id="listModel"/>
    </j:model>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalCenteredLayout/>
            </j:beads>

            <j:Card width="340">
                <j:CardHeader>
                    <html:H3 text="Jewel List With ItemRenderer" className="primary-normal"/>
                </j:CardHeader>
                <j:CardPrimaryContent>
                
                    <j:List width="100%" height="300" className="iconListItemRenderer">
                        <j:beads>
                            <js:ConstantBinding
                               sourceID="listModel"
                               sourcePropertyName="iconListData"
                               destinationPropertyName="dataProvider"/>
                        </j:beads>
                    </j:List>
                    
                </j:CardPrimaryContent>
            </j:Card>
        </j:View>
    </j:initialView>

</j:Application>

By default, Apache Royale Jewel List-based controls display their data as plain text using ListItemRenderer. But Royale is capable of much more, and you can extend ListItemRenderer to display the items in your list in a pleasing and user-friendly way.

In this example we created an IconListItemRenderer in mxml that extends ListItemRenderer:

<?xml version="1.0" encoding="utf-8"?>
<j:ListItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
                    xmlns:j="library://ns.apache.org/royale/jewel"
                    xmlns:js="library://ns.apache.org/royale/basic"
                    xmlns:html="library://ns.apache.org/royale/html">

    <fx:Script>
        <![CDATA[
            import vos.IconListVO;
            
            [Bindable("dataChange")]
            public function get iconList():IconListVO
            {
                return data as IconListVO;
            }
        ]]>
    </fx:Script>

    <j:beads>
        <js:ItemRendererDataBinding />
        <j:HorizontalLayout gap="3" itemsVerticalAlign="itemsCenter"/>
    </j:beads>
    
    <js:MaterialIcon text="{iconList ? iconList.icon : ''}" visible="{iconList ? iconList.icon != null : false}"/>

    <html:Span text="{iconList ? iconList.label : ''}"/>
    
</j:ListItemRenderer>

The list gets its items from the data provider and passes them through the item renderer. The item renderer models each item in a consistent way: it adds a FontIcon to display an appropriate icon (selected, in this case, from the Google Material Icons font) at the left, and the text of the item in a Label to the right. To manage the components for each list item, you can use absolute positioning, layout classes or CSS. We used CSS in the fx:Style section in the main file for simplicity. As you see, the item renderer is declared in CSS as well, and is located in the itemRenderers package.

Note that we use Data Binding, deploying ItemRendererDataBinding. Data binding in Royale is not available by default to reduce code size. You add it where you need it, following the PAYG principle in Royale: Pay As You Go. We add a data binding bead here since we need the function, and not anywhere we don't need it.

The data used in the List control dataProvider is declared in the ActionScript 3 ListsModel class:

package models
{
    import org.apache.royale.collections.ArrayList;
    import vos.IconListVO;

    public class ListsModel 
    {
        /**
         * this is the dataProvider for the List
         */
        private var _iconListData:ArrayList = new ArrayList([
            new IconListVO("Alert", MaterialIconType.WEB_ASSET),
            new IconListVO("Button", MaterialIconType.CROP_7_5),
            new IconListVO("DropDownList", MaterialIconType.CREDIT_CARD),
            new IconListVO("CheckBox", MaterialIconType.CHECK_BOX),
            new IconListVO("Label", MaterialIconType.LABEL),
            new IconListVO("List", MaterialIconType.LIST_ALT),
            new IconListVO("RadioButton", MaterialIconType.RADIO_BUTTON_CHECKED),
            new IconListVO("Slider", MaterialIconType.STORAGE),
            new IconListVO("Text", MaterialIconType.SUBJECT),
            new IconListVO("TextInput", MaterialIconType.TEXT_FIELDS)            
        ]);

        public function get iconListData():ArrayList
        {
            return _iconListData;
        }
    }
}

The MaterialIconType class uses the icon names as they appear in the Material Icons font for convenience and to avoid typos. One additional benefit of using MaterialIconType in your code is that it injects the font into your html directly, without you having to deal with that step.

This class uses a data object (DOT, or POJO, depending on how you name this kind of code), called IconListVO to instance each piece of data that will appear in the List control.

Here's the result of this code snippet:

package vos
{
    [Bindable]
    public class IconListVO
    {
        public var label:String;
        public var icon:String;

        public function IconListVO(label:String, icon:String = null)
        {
            this.label = label;
            this.icon = icon;
        }
    }
}

In the main file, note how we link the ListsModel class through the model variable accessible throughout Royale to make it easy to link a model as a bead.

Finally, we link the model data to the list dataProvider using data binding, with ApplicationDataBinding (since we are at the Application level) and the ConstantBinding class that knows where the data is located (sourceID), what property holds it (iconListData) and where to inject the data (destinationPropertyName).

Hope you like this example 🙂

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

]]>
Using View States to show or hide content https://royale.apache.org/blog/using-view-states-to-show-or-hide-content/ Wed, 06 Jun 2018 24:00:00 GMT https://royale.apache.org/blog/using-view-states-to-show-or-hide-content/ This example shows you how to display or hide content in your Royale application, thanks to the View States feature. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html">
    
    <j:initialView>
        <j:View id="view">
            <j:states>
                <js:State name="login" />        
                <js:State name="loggedIn" />        
            </j:states>
            
            <j:beads>
                <js:SimpleStatesImpl/>
            </j:beads>

            <j:Card id="loginForm" includeIn="login">
                <html:H1 text="Royale login"/>
                <j:TextInput id="username" text="someuser"/>
                <j:TextInput id="password" text="somepass">
                    <j:beads>
                        <j:PasswordInput/>
                    </j:beads>
                </j:TextInput>
                <j:Button text="Login" emphasis="primary" click="view.currentState = 'loggedIn'" />
            </j:Card>

            <j:Card id="loggedInForm" includeIn="loggedIn">
                <html:H1 text="You are logged in!! :)"/>
                <j:Button text="Logout" click="view.currentState = 'login'"/>
            </j:Card>
        </j:View>
    </j:initialView>

</j:Application>

The View States feature is a way of putting different filters over part of the application so that different things appear depending on what the app is doing, what permissions the user has, what the user has just done, or some other condition. You create a series of "states" and associate components of your application with one or more of the states. The way you associate a component with a state is to add the includeIn attribute to the component and set the attribute equal to one or more of the available states. Once you have associated a parent component to a state, all of its children (the things "inside" it) are also associated to the state.

Using states gives you a lightweight and quick way of updating what the user sees, without having to provide all sorts of modules that have to be loaded and unloaded.

The example shows using states to switch between two Card components, what you see before logging in and what you see once you have logged in. To make this work you need to add the SimpleStatesImpl bead. Then define the states you need in the State class. Here, our two states are login and loggedIn. Finally, add an "includeIn" attribute to each Card component and associate it with a state.

When you first see the app, the currentState in the view is the first state listed in the State class: login.

When you click the button, the "click" function assigns a new state as the currentState. Anything that is not associated with the new state magically disappears, and anything that is associated with it is suddenly visible.

Instead of using includeIn, you have another way via dot notation in attributes, in this case notice the notation visible="true" and visible.<state>="false" in the following code:

<j:Card id="loginForm" visible="true" visible.loggedIn="false">
    <html:H1 text="Royale login"/>
    <j:TextInput id="username" text="someuser"/>
    <j:TextInput id="password" text="somepass">
        <j:beads>
            <j:PasswordInput/>
        </j:beads>
    </j:TextInput>
    <j:Button text="Login" emphasis="primary" click="view.currentState = 'loggedIn'" />
</j:Card>

<j:Card id="loggedInForm" visible="false" visible.loggedIn="true">
    <html:H1 text="You are logged in!! :)"/>
    <j:Button text="Logout" click="view.currentState = 'login'"/>
</j:Card>

You can use it in almost any attribute you want, not only visible.

Another way to set SimpleStatesImpl is vía CSS. You can do this in MXML or in an external CSS file:

@namespace "//www.w3.org/1999/xhtml";
@namespace js "library://ns.apache.org/royale/basic";
    
global {
    IStatesImpl: ClassReference("org.apache.royale.core.SimpleStatesImpl");
}

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

]]>
Selecting options from a group of Jewel CheckBox controls https://royale.apache.org/blog/selecting-options-from-a-group-of-jewel-checkbox-controls/ Tue, 22 May 2018 24:00:00 GMT https://royale.apache.org/blog/selecting-options-from-a-group-of-jewel-checkbox-controls/ In this example we'll show a set of Jewel CheckBox controls that let the user select one or more options in a Royale application. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:html="library://ns.apache.org/royale/html">

    <fx:Script>
        <![CDATA[
           private function checkboxChanged(event:Event):void
            {
               result.text = "The options selected are: ";
               
               if(chk1.selected)
                   result.text += chk1.value + " ";
               if(chk2.selected)
                   result.text += chk2.value + " ";
               if(chk3.selected)
                   result.text += chk3.value;
            }
        ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalLayout gap="10"/>
            </j:beads>

            <html:H2 text="Selecting options from a group of Jewel Checkbox controls"/>
            
            <j:Label text="Which option(s) do you prefer?"/>
    
            <j:CheckBox id="chk1" text="Option 1" value="1" change="checkboxChanged(event)"/>
            <j:CheckBox id="chk2" text="Option 2" value="2" change="checkboxChanged(event)"/>
            <j:CheckBox id="chk3" text="Option 3" value="3" change="checkboxChanged(event)">
                <j:beads>
                    <j:Disabled id="opt3disable" disabled="false"/>
                </j:beads>
            </j:CheckBox>

            <j:Label id="result" text="The options selected are:"/>

            <j:Button text="disable/enable option 3" emphasis="primary" click="opt3disable.disabled = !opt3disable.disabled"/>
        </j:View>
    </j:initialView>

</j:Application>

The CheckBox is a two-state button control with the following properties available:

  • text: The label description for the CheckBox
  • value: The internal value of the CheckBox
  • selected: If this is true it means that the CheckBox is selected; it is false otherwise

Each checkbox has CLICK and CHANGE events. CLICK is dispatched when the user clicks the CheckBox, either to select it or to remove the selection. CHANGE is dispatched when the CheckBox is selected/unselected, and is used in this example to update a label with the value properties of all selected check boxes.

As a bonus, you can provide the ability to disable/enable any of the check boxes (and any other Jewel control) by adding the Disabled bead to it. In the example, see if you can have Option 3 both selected and disabled!

Adding beads lets you extend what controls can do by composition, rather than being limited to what the control inherits. The Disabled bead lets you enable or disable the control programmatically, depending on whatever you find important for your application (for instance, whether the user is logged in or has made a selection in another control that is required before selecting one of these options). We'll be talking more about beads in future posts.

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

]]>
Binding the text property of a Jewel TextInput to update a text Label https://royale.apache.org/blog/binding-the-text-property-of-a-jewel-textinput-to-update-a-text-label/ Wed, 09 May 2018 24:00:00 GMT https://royale.apache.org/blog/binding-the-text-property-of-a-jewel-textinput-to-update-a-text-label/ In this example we'll cover how to use the data binding feature with a Jewel TextInput field in a Royale application. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic">
    <fx:Script>
        <![CDATA[
           private function textChanged(event:Event):void
            {
                result.text = "The textinput text value is: " + textinput.text;
            }
        ]]>
    </fx:Script>

    <j:beads>
        <js:ApplicationDataBinding />
    </j:beads>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalLayout gap="10"/>
            </j:beads>

            <j:Label text="Binding the text property of a Jewel TextInput field to update a text Label"/>

            <j:TextInput id="textinput" change="textChanged(event)">
                <j:beads>
                    <j:TextPrompt prompt="Using change event"/>
                </j:beads>
            </j:TextInput>

            <j:Label id="result" text="The TextInput field text value is: "/>

            <j:TextInput id="databinding_ti">
                <j:beads>
                    <j:TextPrompt prompt="Using databinding"/>
                </j:beads>
            </j:TextInput>

            <j:Label text="The TextInput field text value is: {databinding_ti.text}"/>
        </j:View>
    </j:initialView>

</j:Application>

Data binding is a general technique that binds together and synchonizes data from a provider, or source (in this case the contents of the text property of a TextInput field), and a consumer (in this case the text property of a Label). You can use data binding with many controls, variables and components to provide a powerful user experience. You can bind a List as the data provider for an ArrayList variable so the ArrayList displays details of the item the user selects in the List. Changing a Slider's value can change the width of a control or container the Slider is bound to.

In Apache Royale, you can configure data binding at different levels: Application, View, Container, ItemRenderer, and more. This follows the PAYG (Pay As You Go) philosophy that is key to the global design of Apache Royale. PAYG keeps an application as lightweight as possible, since you only add many features and functions to the components that actually need them. Other front-end technologies follow a "just in case" model of providing every possible function to each component even though most of those features, and the weight of that code, will serve no good use. In Royale you stay light and agile by declaring features like data binding only if the application, or some part of it, needs them.

In this example, we use data binding at the application level, since the whole example is only a few lines of code. So we use the ApplicationDataBinding bead. This bead adheres to the Application strand, "composing" or "adding" the binding functionality at the application level. In a more complex application, you might decide you only need data binding in a particular View or Container. Then you could use a ViewDataBinding bead, or a ContainerDataBinding bead. PAYG ensures features like data binding are only present where you really need them, and not using up system resources by sitting around in parts of the application where they will never be used.

In our example the first TextInput control uses a normal CHANGE event handler to update the text property of the Label field below it. The second TextInput control uses data binding to update the Label below it. You get the same result, but in different ways.

Notice that both TextInput controls use a TextPrompt bead that adds the prompt functionality to the control. We wanted that feature for this example; but since not every TextInput control in every application has to have a prompt, you "pay" for the function by adding the TextPrompt bead only where you need it: PAYG!

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

]]>
Creating a group of Jewel radio buttons https://royale.apache.org/blog/creating-a-group-of-jewel-radiobuttons/ Wed, 02 May 2018 24:00:00 GMT https://royale.apache.org/blog/creating-a-group-of-jewel-radiobuttons/ In this example we'll cover how to show a list of options in a Royale application with a group of Jewel RadioButton controls. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:html="library://ns.apache.org/royale/html">
    
    <fx:Script>
        <![CDATA[
           private function radioChanged(event:Event):void
            {
                result.text = "The radio button selected has the value: " + RadioButton(event.target).value;
            }
        ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalLayout gap="10"/>
            </j:beads>

            <html:H2 text="Creating a group of Jewel RadioButtons"/>
            
            <j:Label text="Which option do you prefer?"/>
    
            <j:RadioButton text="Option 1" groupName="radios" value="1" change="radioChanged(event)"/>
            <j:RadioButton text="Option 2" groupName="radios" value="2" change="radioChanged(event)"/>
            <j:RadioButton text="Option 3" groupName="radios" value="3" change="radioChanged(event)">
                <j:beads>
                    <j:Disabled id="opt3disable" disabled="false"/>
                </j:beads>
            </j:RadioButton>

            <j:Label id="result" text="The radio button selected has the value:"/>

            <j:Button text="disable/enable option 3" emphasis="primary" click="opt3disable.disabled = !opt3disable.disabled"/>
        </j:View>
    </j:initialView>

</j:Application>

The radio buttons have these properties available:

  • text: The label description for the radio button
  • value: The internal value of the radio button
  • selected: If this is true it means that the radio button is selected; it is false otherwise
  • groupName: All radio buttons with the same group name are related, so the user can change which radio button is selected but can never select more than one member of the group at a time

Each radio button has CLICK and CHANGE events. CLICK is dispatched when the user clicks the RadioButton. CHANGE is dispatched when the RadioButton is selected/unselected, and is used in this example to update a label with the value property of the selected radio button.

As a bonus, you can provide the ability to disable/enable any of the radio buttons (and any other Jewel control) by adding the Disabled bead to it. Adding beads lets you change what controls can do by composition, rather than being limited to what the control inherits. The Disabled bead lets you enable or disable the control programmatically, depending on whatever you find important for your application (for instance, whether the user is logged in or has made a selection in another control that is required before selecting one of these options). We'll be talking more about beads in future posts.

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

]]>
Adding an item to a Jewel List https://royale.apache.org/blog/adding-an-item-to-a-jewel-list/ Mon, 16 Apr 2018 24:00:00 GMT https://royale.apache.org/blog/adding-an-item-to-a-jewel-list/ In this example we'll cover how to set up a Jewel List control that shows a list of basic string data in a Royale application, and then add an item to the list. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html">
    
    <fx:Script>
        <![CDATA[
           private function changeHandler(event:Event):void {
               selected.text = "Selected: " + list.selectedItem;
           }
           
           private function clickHandler(event:Event):void {
               avengersCharacters.addItem("Hawkeye");
           }
        ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalLayout gap="10"/>
            </j:beads>
            
            <html:H3 text="Avengers Character List"/>
    
            <j:List id="list" width="200" height="300" change="changeHandler(event)">
                <j:beads>
                    <j:AddListItemRendererForArrayListData/>
                </j:beads>
                <j:dataProvider>
                    <js:ArrayList id="avengersCharacters" source="[Iron Man, Hulk, Thor, Captain America, Black Widow]" />
                </j:dataProvider>
            </j:List>
            <j:Label id="selected"/>

            <j:Button width="200" emphasis="primary" text="who is missing?" click="clickHandler(event)"/>
        </j:View>
    </j:initialView>

</j:Application>

In this example, the List is populated from an ArrayList object that holds a basic array of the data. The ArrayList has all collection methods to manage internal data, like addItem and addItemAt. We used Avengers character names to showcase this example, but you'll see one character is missing ;). For this example we used the Amethyst Jewel Theme to match movie colors better.

When you select a row in the List a CHANGE event is fired. We have the event call an event handler that shows the data for the selected item in a label.

Finally you can click the "Who's missing?" button to add the missing Avenger to the list. The List will update to reflect the addition. For this to happen you'll need to use a bead that encapsulates the code responsible of adding the item to the data provider and create the corresponding item renderer called AddListItemRendererForArrayListData.

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

]]>
Using the Jewel Slider Control https://royale.apache.org/blog/using-the-jewel-slider-control/ Thu, 12 Apr 2018 24:00:00 GMT https://royale.apache.org/blog/using-the-jewel-slider-control/ In this example we'll see the basic use of the Jewel Slider control in a Royale application. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel">
    
    <fx:Script>
        <![CDATA[
        
        private function clickHandler(event:MouseEvent):void
        {
            slider_w.value = 400;
            slider_h.value = 200;
        }

        private function onValueChange(event:Event):void
       {
            button.width = slider_w.value;
            button.height = slider_h.value;
            button.text = slider_w.value + "x" + slider_h.value;
        }
        ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:beads>
                <j:VerticalLayout gap="10"/>
            </j:beads>

            <j:Slider id="slider_w" width="250" value="250" minimum="100" maximum="500"
               valueChange="onValueChange(event)"/>

            <j:Slider id="slider_h" width="250" value="80" minimum="40" maximum="300"
               valueChange="onValueChange(event)"/>

            <j:Button id="button" text="Slider to 400x200" width="250" height="80" emphasis="secondary"
               click="clickHandler(event)"/>
        </j:View>
    </j:initialView>
    
</j:Application>

In this example, you can click the Jewel button to set up slider values. When you do this the ValueChangeEvent.VALUE_CHANGE will fire, calling the onValueChange event handler and setting width, height and text in the Button.

On the other hand, you can drag each slider to change width and height in the Button, and function to update value in "onValueChange" will be called continuously as you drag the slider controls.

You can click in the track at any place to change the value immediately to the value at that point in the track. And if you need them, you have available "input" and "change" events in Slider. The first fires each time you move the slider thumb from one position to another, and the second fires when Slider ends its change from one position to another.

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

]]>
Using the Jewel Alert Control https://royale.apache.org/blog/using-jewel-alert-control/ Fri, 06 Apr 2018 24:00:00 GMT https://royale.apache.org/blog/using-jewel-alert-control/ The following code shows the basic method for displaying an Alert dialog in a Royale application. It uses the new Jewel UI set that supports themes and is available in the 0.9.4 release or later.
<?xml version="1.0" encoding="UTF-8"?>
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel">
    
    <fx:Script>
        <![CDATA[
           import org.apache.royale.jewel.Alert;
           import org.apache.royale.events.CloseEvent;

          private function clickHandler(event:MouseEvent):void {
              var alert:Alert = Alert.show("Do you want to save your changes?", "Save Changes", Alert.YES | Alert.NO);
              alert.addEventListener(CloseEvent.CLOSE, alertClickHandler);
          }
      
          private function alertClickHandler(event:CloseEvent):void {
              if (event.detail == Alert.YES)
                  button.text="You answered Yes";
              else
                  button.text="You answered No";
          }
       ]]>
    </fx:Script>

    <j:initialView>
        <j:View>
            <j:Button id="button" text="Click Me" emphasis="primary" click="clickHandler(event)"/>
        </j:View>
    </j:initialView>
    
</j:Application>

In this example, the Jewel button adds a click handler that will be in charge of showing the Alert control. When the user clicks the button the Alert.show() static method is called. You can add a custom message, a custom title and choose which buttons will be created for that instance of the Alert.

Finally, the Alert instance adds an event listener to manage the alert response when the dialog is closed. In this example we're changing the label of the button according to the button the user clicks in the Alert.

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.2 released! https://royale.apache.org/blog/apache-royale-v0-9-2-released/ Mon, 19 Mar 2018 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-2-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.2.

The Apache Royale project is a continuation of the previous effort called FlexJS to produce a next-generation of the Apache Flex SDK that enables developers to use MXML and ActionScript to generate HTML/JS/CSS applications which can run natively in browsers. The cross-compiled code can also be used in Apache Cordova (Adobe PhoneGap) mobile applications.

This release should be considered 'beta' quality. The purpose of this release is to gather feedback about the features and 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 may not handle production needs.

Changes in 0.9.2:

  • Added ApplicationParametersBead and ApplicationParametersCaseInsensitiveBead
  • Added virtual item renderer management for fixed row height vertical lists.
  • Added Menu and MenuBar
  • Added DividedBox
  • Many CSS default values are now in the basic.css theme.
  • Theme support. Now compiler will copy all resources in "assets" folder to target
  • Added JSON2ASVO, a utility that creates AS classes from a JSON result
  • Added JSONReviver, a class that converts JSON to AS classes sort of like AMF
  • Added HScrollViewport
  • Added VScrollViewport
  • Fixed bugs in XML parsing and converting back to strings
    • https://github.com/apache/royale-asjs/issues/120
    • https://github.com/apache/royale-asjs/issues/121
    • https://github.com/apache/royale-asjs/issues/122
    • https://github.com/apache/royale-asjs/issues/123
  • Fixed Maven distribution so you can use in IDEs like VSCode, Moonshine and more.
    • https://github.com/apache/royale-asjs/issues/125

You can see more here.

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 bugs in the framework or compiler.

For questions about how to use Royale, send email to mailto:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Apache Royale v0.9.1 released! https://royale.apache.org/blog/apache-royale-v0-9-1-released/ Wed, 14 Feb 2018 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-1-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.1.

The Apache Royale project is a continuation of the previous effort called FlexJS to produce a next-generation of the Apache Flex SDK that enables developers to use MXML and ActionScript to generate HTML/JS/CSS applications which can run natively in browsers. The cross-compiled code can also be used in Apache Cordova (Adobe PhoneGap) mobile applications.

This release should be considered 'beta' quality. The purpose of this release is to gather feedback about the features and 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 may not handle production needs.

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 bugs in the framework or compiler.

For questions about how to use Royale, send email to mailto:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>
Creating a Hello World in Apache Royale https://royale.apache.org/blog/creating-a-hello-world-in-apache-royale/ Mon, 12 Feb 2018 24:00:00 GMT https://royale.apache.org/blog/creating-a-hello-world-in-apache-royale/ This section will try to bring simple code examples that should help to develop with Apache Royale more quickly. This is in part a tribute to Peter deHaan blogs he did for Apache Flex, ActionScript 3 and Adobe AIR some years ago. Hope you like it and want to contribute to get a huge library of Royale code snippets well organized and searchable.

So lets begin with our first code snippet: Hello World.

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
            xmlns:js="library://ns.apache.org/royale/basic">

    <js:valuesImpl>
        <js:SimpleCSSValuesImpl />
    </js:valuesImpl>

    <js:initialView>
        <js:View>
            <js:Label text="Hello World" />
        </js:View>
    </js:initialView>
</js:Application>

In this example you can see the use of the following MXML tags:

  • Application: Is the main tag in your application. All content in Apache Royale is added inside this tag.
  • SimpleCSSValuesImpl: This class implements a minimal set of CSS rules that is sufficient for most applications.
  • View: This is the class for most views in a Royale application.
  • Label: Implements the basic control for show a label with text.

Where to go from here

The result of this "Hello World" 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.0 released! https://royale.apache.org/blog/apache-royale-v0-9-0-released/ Tue, 30 Jan 2018 24:00:00 GMT https://royale.apache.org/blog/apache-royale-v0-9-0-released/ The Apache Royale community is pleased to announce the release of Apache Royale 0.9.0.

The Apache Royale project is a continuation of the previous effort called FlexJS to produce a next-generation of the Apache Flex SDK that enables developers to use MXML and ActionScript to generate HTML/JS/CSS applications which can run natively in browsers. The cross-compiled code can also be used in Apache Cordova (Adobe PhoneGap) mobile applications.

This release should be considered 'beta' quality. The purpose of this release is to gather feedback about the features and 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 may not handle production needs.

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 bugs in the framework or compiler.

For questions about how to use Royale, send email to mailto:[email protected]. For questions and feedback on the development of the source code in the release, send email to [email protected].

Enjoy! 🙂

]]>