pod flux

Flux: Core Application

Classes

CommandId

Commonly used FluxCommand ids for the commands built-in into the flux runtime.

Console

Console is used to run external programs and capture output.

ErrResource

ErrResource models a resource that cannot be resolved.

FileResource

FileResource models a File as a Flux resource.

FindHistory

FindHistory maintains the most recent find text queries for the entire application.

Flux

Flux provides system level utilities for flux applications

FluxCommand

Flux specialization of normal fwt commands.

Frame

Frame is the main top level window in flux applications.

GeneralOptions

GeneralOptions is a catch-all for general purpose options.

History

History maintains the most recent navigation history of the entire application.

HistoryItem

HistoryItem stores information about navigation to a specific uri.

HistoryPicker

HistoryPicker

KeyOptions

KeyOptions allow the user to redefine accelerators for the flux command set.

LoadMode

LoadMode is used to configure how a resource is loaded into view such as whether to use a new tab.

Mark

Mark is used to identify a uri with an optional line and column position.

Resource

Resource represents the objects a user navigates, views, and edits in a flux application.

SideBar

SideBar is a plugin used along side the main views.

View

View is a plugin designed to view or edit a Resource.

Overview

Flux is a framework for building general purpose desktop applications with the fwt toolkit. This chapter covers how to use the flux APIs for creating new applications and plugins. See docTools for how to setup and use flux as an IDE.

Flux is based on a browser navigation model. Users navigate Uris which are resolved to resources. Users interact with resources through views which are used to view and edit the resources. The next sections cover resources and views in detail.

The Flux chrome works very much like a traditional browser. It handles navigation, history, and view tabs. It provides a plugin model for adding sidebars which are used independently of views.

Resources

Resources are the objects a user browses, views, and edits in a flux application. Resources are modeled by the Resource class. The Resource class typically wraps some other Fantom object to define how it is presented in the user interface such as its name, icon, the available views, and children if tree structured.

The most common resource is FileResource which is used to wrap a File instance. FileResource uses MIME type to map files to their icon and available views.

Views

Views are user interface components which subclass from ContentPane. A view is how a user interacts with a resource for visualizing and/or editing. Views are model by the View class.

View Lifecycle

The view lifecycle typically involves these steps:

  1. Construction: when your view's constructor is called you don't have access to the parent frame or resource; so typically you won't do much in your constructor.
  2. onLoad: the onLoad callback is invoked when the view should load its UI state from the resource. At this point both View.frame and View.resource are available. However your view has not been mounted into the into the widget tree yet.
  3. dirty: if your view is an editor, then you should set the dirty field to true when the user makes a modification to the resource.
  4. onSave: the framework will determine when the user wishes to save your view. This might happen from the Save or Save All commands, or might occur from a close prompt. The view should save the UI state back to the actual resource - for example if editing a file, then the view will rewrite the file. Once onSave completes, the dirty flag is set back to false.
  5. onUnload: this callback is invoked when the view is being unloaded, typically because navigating to a new resource or view.

In addition to the above, views receive the onActive and onInactive callbacks when the view is selected and unselected as the active tab. The onActive callback is used to enable predefined view managed commands such as find and replace.

When a user navigates to a Uri, the flux runtime performs the following process to resolve the resource and views:

Uri Resolution

The step of navigation is to resolve the Uri to a normal Fantom Obj using the standard naming facilities. This means that any Uri which has been mapped via a UriScheme is available for navigation.

Resource Resolution

Uri resolution maps the Uri to a normal Fantom object. But we really want a Resource instance so that we know how to display the object in our UI. If the object from uri resolution is already an instance of Resource, then we don't need to do anything special.

If the object from uri resolution is not a Resource, then we search the indexed props for a Resource keyed by the flux.resource.{qname} prop for the object's type (and we search its base classes). The FileResource class is automatically registered to handle sys::File. For example to map an instance of AppRec to AppResource:

class AppResource : Resource
{
  new (Uri uri, AppRecord rec) { this.uri = uri; this.rec = rec }
  override Uri uri
  override Str name() { ... }
  override Image icon() { ... }
  AppRecord rec
}

// build.fan
index = ["flux.resource.myPod::AppRec": "myPod::AppResource"]

If you map a Resource subclass, then you need to ensure that your make constructor takes Uri as its first parameter, and the mapped object as its second parameter.

View Resolution

Once we've resolved the uri to a resource instance, the next step is to discover which views are available to view and edit the resource. The list of available views is deferred to the Resource.views method. The first view in the list should be default view.

The default strategy for resolving views by Resource.views is to query index props for any View keyed by the flux.view.{resource} using the resource's type. For example to register AppView on AppResource:

class AppView : View
{
  override Void onLoad() { ... }
}

// build.fan
index = ["flux.view.myPod::AppResource": "myPod::AppView"]

If working with files, then you typically register a view by MIME type. The follow indexed prop keys are used:

// register on text/*
flux.view.mime.text

// register on text/xml
flux.view.mime.text/xml
internal class MyXmlView : View

// register on multiple MIME types
flux.view.mime.text/xml
flux.view.mime.text/html

View Query

The default view used to work with a resource is the first view in the list returned by Resource.views. Alternate views are selected in the Uri's query map with a view key and qualified view typename as the value:

file:/home/file.txt?view=fluxText::TextEditor

Typically the flux chrome will handle displaying the list of available views and allowing the user to choose alternate views.

A SideBar is a plugin which exists independent of resources and views. Sidebars are widgets which may be opened along the left, bottom, or right edges of the view pane. SideBars are registered with the flux.sideBar indexed prop. A very simple sidebar:

class ExampleSideBar : SideBar
{
  new make() { content = Label {"Example SideBar" } }
}

// build.fan
index = ["flux.sideBar": "myPod::ExampleSideBar"]

There is one instance of a SideBar per registered type for each Frame. The SideBar is instantiated in memory the first time the user shows it within a given frame. After that the instance is mounted and unmounted from the frame using show and hide.

Typically the user manages the sidebars via the View menu. The id for each sidebar command on the View menu is that SideBar's type name, and localization is based on the type's pod. You can setup icons and accelerators using the normal conventions via localization.

SideBars receive a set of callbacks to manage their lifecycle and respond to view selections:

  • onLoad: called when loaded into memory; good place to load persistent state
  • onUnload: called when unloaded from memory; good place to save persistent state
  • onShow: called when shown on frame
  • onHide: called when hidden on frame
  • onActive: called when user links to new resource or selects new tab
  • onInactive: called when current view is replaced with new view or tab