Learning Employee Directory 3. UI

2 min read

Return to table of contents

When I downloaded and launched ED, I was impressed by its elegant user interface. So how is implemented?

The relevant files are:

And the hierarchy of UI is shown below. I expand each custom component (except EmployeeView and DepartmentView). In principle, one can imagine that we can put all the components into a single file (ApplicationUI.mxml) but it will be too complicated to manipulate. Also, this application used state to control the user interface. If you are not familiar with state, you may read flex documentation.

Following the hierarchy of UI, the first file we encounter is actually the root mxml file: employeedirectory.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:application mx="http://www.adobe.com/2006/mxml" layout="absolute" ui="com.adobe.empdir.ui.*" applicationcomplete="onApplicationComplete()" height="400" width="320" horizontalscrollpolicy="off" verticalscrollpolicy="off" activate="alpha=1" deactivate="alpha=0.9">
  
 <mx:script>
  <![CDATA[    private function onApplicationComplete() : void    {     ui.init();    }    ]]>
 </mx:Script>
 
 <mx:style source="employeedirectory.css">
 
 <ui:applicationui id="ui" width="100%" height="100%">
</mx:Application>

I intentionally leave out the logging part for simplicity. Let’s digest this file line by line:

<mx:application mx="http://www.adobe.com/2006/mxml" layout="absolute" ui="com.adobe.empdir.ui.*" applicationcomplete="onApplicationComplete()" height="400" width="320" horizontalscrollpolicy="off" verticalscrollpolicy="off" activate="alpha=1" deactivate="alpha=0.9">

Using Application instead of WindowedApplication is actually necessary to create a transparent-window application (in AIR beta 3). I tried to change Application to WindowedApplication and found I can’t get rid of the default minimize, maximize and close button.

XML name space is important. It tells the compiler where to find your custom components: ApplicationUI.

height and width are not what the size of the window you see because the transparent background are part of the application. So height and width are not important as long as their values are larger than 400×320. You can try 800×600.

This line also tells the application to respond several events: applicationComplete, activate and deactivate. The latter two are simply fancy effects. The first one is to initialize the application.

ui.init(); 

The initialization code is simple — just call the initialization code in ApplicationUI.

<mx:style source="employeedirectory.css"> 

You can imagine a lot of visual component has custom styles. The file controls such styling is in employeedirectory.css. See 3.1 style for more about style.

<ui:applicationui id="ui" width="100%" height="100%">

This is the most important line in this file. It adds a custom component, called ApplicationUI, into the main application.

OK, we need to get the next file, ApplicationUI.mxml, following the hierarchy. The file is located under directory com.adobe.empdir.ui. It is the main UI file. All other visual components are children of ApplicationUI.

<?xml version="1.0" encoding="utf-8"?>

<mx:canvas mx="http://www.adobe.com/2006/mxml" ui="com.adobe.empdir.ui.*" currentstate="info" horizontalscrollpolicy="off" verticalscrollpolicy="off">

 <!-- The draggable background area -->
 <ui:backgroundbox id="bgBox" width="{ contentBox.width }" height="{ contentBox.height }" stylename="bgBox" mousedown="stage.window.startMove()">
 
 <!-- The main content area -->
 <mx:vbox id="contentBox" minwidth="310" minheight="70" stylename="contentBox" horizontalscrollpolicy="off" verticalscrollpolicy="off" resizeeffect="Resize" verticalgap="3">
  <ui:titlecontrols id="titleControls" width="100%">
 </mx:VBox>
 
 <mx:states>
  <mx:state name="info">
   <mx:addchild relativeto="{ titleControls }" position="after">
    <mx:label id="infoLabel" color="#CCCCCCC">
   </mx:AddChild>
  </mx:State>
  
  <mx:state name="help">
    <mx:addchild relativeto="{ titleControls }" position="after">
     <ui:helpview creationcompleteeffect="Fade" horizontalscrollpolicy="off" verticalscrollpolicy="off" width="290" height="340">   
    </mx:AddChild>
  </mx:State>
  
  <mx:state name="main">
   <mx:addchild relativeto="{ titleControls }" position="after">
    <ui:maincontentcontainer>
   </mx:AddChild>
  </mx:State>
  
  <mx:state name="error">
   <mx:addchild relativeto="{ titleControls }" position="after">
    <mx:textarea id="errorLabel" color="#FF0000" width="100%" height="100" backgroundalpha="0" bordercolor="#454545" editable="false">
   </mx:AddChild>
  </mx:State>
 </mx:states>
 
</mx:Canvas>

I left the script part out to highlight the visual component. We see that this ApplicationUI is a Canvas with some components inside. Note, Canvas is the only container that lets you explicitly specify the location of its children within the container by using the x and y properties of each child.

In ApplicationUI, we have a BackgroundBox, a custom component. By its name we guess it is the background. Its size is bound to the size of contentBox. If you open BackgroundBox.mxml, you will find it’s simply a VBox with drop shadow effect.

We also have a VBox (called contentBox) where the visual stuff is, including the TitleControls (logo text, the minimize button etc). Depending on different states, extra components will be added into the VBox.

First, let’s see how the logo text, the minimize/close button are organized. See TitleControls.mxml.

<mx:hbox mx="http://www.adobe.com/2006/mxml" horizontalalign="left" verticalalign="middle" mousedown="stage.window.startMove()">
 <mx:canvas y="5">
  <mx:label stylename="textBold" fontsize="12" text="EMPLOYEE DIRECTORY" color="#FFFFFF">
  </mx:Label>
 </mx:Canvas>
 
 <mx:hbox verticalalign="bottom" horizontalgap="2" width="100%" horizontalalign="right">
  <mx:vbox verticalalign="center">
   <mx:label id="versionLabel" color="#777777" height="12" fontsize="10">
  </mx:VBox>
  <mx:button stylename="appHelpButton" click="dispatchEvent( new Event('showHelp') )">
  <mx:spacer width="1">
  <mx:button stylename="appMinimizeButton" click="stage.window.minimize()" tabenabled="false">
  <mx:button stylename="appCloseButton" click="stage.window.close()" tabenabled="false">
 </mx:HBox>
</mx:HBox>

TitleControls is a HBox as expected: the components are aligned left to right. From left to right, we see the logo text “EMPLOYEE DIRECTORY” (If you are using beta2 version you will see it is more fancy). You see another HBox, which contains the help button, minimize/close buttons. It is important to set the width of this HBox 100% and horizontalAlign right to makes these button appear on the right corner. Clicking these buttons also dispatch events or simply minimize/close the window.

Good, we have the logo and some essential buttons. In ApplicationUI you find depending on states, extra component will be added:

  1. If the state is “info”, a Label will be added under the TitleControls.
  2. If the state is “help”, a HelpView will be added under the TitleControls.
  3. If the state is “main”, a MainContentContainer will be added under the TitleControls.
  4. If the state is “error”, a TextArea will be added under the TitleControls.

Label and TextArea are straightforward. HelpView is also simple:

<mx:canvas mx="http://www.adobe.com/2006/mxml" stylename="dataPanel" data="com.adobe.empdir.util.*" controls="com.adobe.empdir.controls.*">

  
 <mx:button id="closeBtn" stylename="closePanelButton" click="dispatchEvent( new Event( Event.CLOSE, true ) )" y="2" x="{ width - (closeBtn.width + 4) }" usehandcursor="true">
 
 
 <mx:vbox width="100%" height="100%" stylename="contentBox" paddingtop="15">
  
  
  <!-- The top icon and title -->
  <mx:hbox width="100%" verticalalign="top" horizontalgap="10" horizontalalign="left">
   <mx:image id="logoImage" source="@Embed('/embed_assets/helpapp_icon.png')" tooltip="Last updated: { dataSyncManager.lastUpdated }" click="dataSyncManager.sync()">
   
   <mx:vbox horizontalalign="left" verticalalign="top" verticalgap="0">
    <mx:label text="About Employee Directory" fontsize="15" stylename="dataPanelText" fontweight="bold" height="20">
    <mx:label text="{ versionLabel }" stylename="dataPanelText">
   </mx:VBox>
  </mx:HBox>
  
  <mx:vbox width="100%" height="100%">
   <mx:textarea width="100%" height="100%" backgroundalpha="0" borderstyle="none" themecolor="Black" stylename="dataPanelText" htmltext="{ htmlText }" fontsize="11">
  </mx:VBox>
  
 </mx:VBox>
 
</mx:Canvas>

It is a Canvas with a close button on right and a VBox. In side VBox, you find the logo image and some text.

It should be noted that clicking the close button will dispatch a event new Event( Event.CLOSE, true ). The true argument makes this event bubble and be captured by parent component.

Now the MainContentContainer component. We can imagine by our experience with the application that it should contains a text input area for searching, and a employee or department view.

<mx:vbox mx="http://www.adobe.com/2006/mxml" controls="com.adobe.empdir.controls.*" employee="com.adobe.empdir.ui.employee.*" dept="com.adobe.empdir.ui.dept.*" creationcomplete="onCreationComplete()" resizeeffect="Resize" horizontalscrollpolicy="off" verticalscrollpolicy="off" verticalgap="10" ui="com.adobe.empdir.ui.*">

  <mx:canvas width="290">
  
   <!-- Dropdown that allows searching for different entities  -->
   <controls:customautocomplete id="searchInput" width="290" height="20" typedtextchange="onTypeTextChanged()">
   </controls:CustomAutoComplete>
    
   <mx:image source="@Embed('/embed_assets/magnifying_icon.png')" right="5" top="3" mouseenabled="false">
  </mx:Canvas>
  
  
  <mx:states>
   <mx:state name="employeeView">
    <mx:addchild>
     <employee:employeeview id="empView" creationcompleteeffect="Fade" horizontalscrollpolicy="off" verticalscrollpolicy="off" width="290" height="300" remove="empView.employee=null">   
    </mx:AddChild>
   </mx:State> 
   
   <mx:state name="departmentView">
    <mx:addchild>
     <dept:departmentview id="deptView" horizontalscrollpolicy="off" verticalscrollpolicy="off" width="290" height="300" remove="deptView.department=null">   
    </mx:AddChild>
   </mx:State>
  </mx:states>
</mx:VBox>

We see it contains a custom search bar (which support auto complete), an image (the magnifying icon. Depending on the states, it will display either employee or department.



写作助手,把中式英语变成专业英文


Want to receive new post notification? 有新文章通知我

How much money did I make from an app?

Undoubtedly some people are very successful in making money by developing a smartphone app. Back in 2012 I developed an app called “Handbook of Brain” which is a collected resources of brain anatomy, function and diseases. I put the app i
Xu Cui
27 sec read

Handy programs to visualize NIRS data (2): plotTopoMap

Often you need to view the spatial pattern of activation as in the example below. plotTopoMap allows you to do that. It probably only works for Hitachi devices where the spatial relationship between channels are known. In the above example, the activ
Xu Cui
37 sec read

Flash 3D video demo

Racer Ostrova Zombie
Xu Cui
0 sec read

Leave a Reply

Your email address will not be published. Required fields are marked *