Beginner’s tutorial – Taking and displaying a photo

A Deeper Dive into the code

 

Quick Overview: Creating an app

Go to Projects by clicking on the briefcase icon in the left menu. Now that you are in Projects you will see the Projects menu above the Projects window. To create a new Project click on the +Create button.

Fill out the pop up form and click Create.

Your project will appear on its own card in the Project window. Click on the Project name. Now that you are inside your project the +Create button will create an app.

Click on +Create and fill out the pop up form. Click Create to create your app.

Your new application will appear on its own card in your Project window. Click on the application to open it. This will open the application in a text editor in the model section of the Mat|r IDE (Integrated Development Environment).

In the left column of the text editor you will see that the file main.ms has been created for you. It contains code for an Experience and a Rules Context to help you get started. The two essential components of every Mat|r application are the experience you are modeling and the rules that govern it.

The Experience we are going to model is taking a photo and displaying it.

First we are going to edit the Experience code. Right now the Experience name is Main let’s change it to PhotoExperience:

// Matr template code, delete/update as needed
Experience PhotoExperience {

Now let’s define the attributes of PhotoExperience. Here is the code for the attributes that will replace the default code:

   Decision takePhoto action('MainContext.takePhoto') label('Take Photo')
String myPhoto as Image
}

Now we are going to modify the RuleContext and the Rule that where created by default. Copy and paste this code over the example code:

RuleContext MainContext {

      Rule takePhoto {
         PhotoExperience expData = broker.ui.getDataSource()
         MediaCameraConfigure mcc = MediaCameraConfigure()
         MediaFile photoData = broker.media.open(mcc)
         if (photoData != null) {
            expData.myPhoto = photoData.getURL()
         }
      }

}

Your code should now look like this:

Experience PhotoExperience {
   Decision takePhoto action('MainContext.takePhoto') label('Take a Photo')
String myPhoto as Image
}

RuleContext MainContext {

      Rule takePhoto {
         PhotoExperience expData = broker.ui.getDataSource()
         MediaCameraConfigure mcc = MediaCameraConfigure()
         MediaFile photoData = broker.media.open(mcc)
         if (photoData != null) {
            expData.myPhoto = photoData.getURL()
         }
   }

}

We will explain what each line of code means in depth in the next section but for now let’s have a look at the app we just created. Switch from Model to Build UI mode by clicking on Build UI in the menu above the text editor.

Editing the UI

Mat|r auto generates a visual representation (a UI) of every Experience you create. The UI that Mat|r generates for an Experience is called a layout. Click on the layouts button on the left. You will see the layout for PhotoExperience. Click on it and the UI for PhotoExperience will appear in the Preview.

In the menu above the right column click on themes. Click on some of the themes until you find one you like. Now click on Properties in the menu above the right column. Select the Take a Photo button in the Preview or from the left menu under Templates / layout. In the right Properties column you can edit the color, border, font, padding, etc of the element you selected.

Go to the menu above the Preview window and switch from UI View to Markup View. Scroll down to Button and you can make the all the same style changes in the markup text editor that you made in the WYSIWYG editor.

Publishing your App and Sharing it.

If this was an app ready for public release we would now publish it to the Apple and Google app stores. Users could then download your native Mat|r app and use it like any other app. But you can also run your Mat|r app on your phone and allow others to run it on their phones without publishing it to the app stores. For that you will need the Mat|r Viewer App on your phone.

Download the Mat|r Viewer so that you can preview the PhotoExperience app on your phone:

Google PlayApp Store

Sign in to the app with your Mat|r username and password.

On your home screen you will see a list of organizations you are a member of. When you sign up, Mat|r creates your account as an organization. That is so you can add team members to your account later if you wish. Click on your organization (account).

Click on your Project

Click on the app you created. Then click on view draft.

Your app will open on your phone. Any future changes you make to the app you will be able to preview on your phone using the Mat|r Viewer App.

A Deeper Dive into Creating an App

Let’s repeat the Photo app exercise and get into the detail of the code line by line.

Go back to the project you created and create a new app. In the New app popup screen: Give your app a name.

Adding a description is optional, but it is good coding practice to make sure your code is well documented. So we suggest you create a description, so that you and anyone you share this app with will know what it is about at a glance.

Select whether you want your app to be public (visible to everyone in Mat|r|hub) or private (only visible to you). Then select if you want to share your app under an open source license (select enabled). This will enable others to import a copy of your app and use it to create their own apps. If you don’t want to share your code just click disabled. When you are done, click create.

Creating an experience

Click on the application to open it.

In the left column you will see the file main.ms has been created for you. It contains code for an Experience and a Rules Context to help you get started. The two essential components of every Mat|r application are the experience you are modeling and the rules that govern it.

The Experience in this example is taking a photo and displaying it. Here is the code template Mat|r gives you to get started:

// Matr template code, delete/update as needed
Experience Main {
    // Add your attributes here
    String name label("Main name")
}

RuleContext MainContext {
    // This rule is called every time the Experience Main is changed 
    Rule firstRule listen (* from Main as exp) {
        // Do something with the exp reference
    }
}

First we are going to edit the Experience code. Right now the Experience name is Main let’s change that to PhotoExperience :

Experience PhotoExperience {

Now let’s define 2 attributes for PhotoExperience. Our new code for the attributes will look like this:

Experience PhotoExperience {

        Decision takePhoto action('MainContext.takePhoto') label('Take Photo')

        String myPhoto as Image

}

Some code definitions:
A String is a sequence of characters.

A Label is a component for placing text in a container. It is used to display a single line of read only text. 

The first attribute is going to be a Decision. What is a Decision in Mat|r?

A Decision defines an action that is taken when certain conditions are met. These conditions are defined in a rule. The rules define how the decision is made and the action that is taken once the decision is made. The Decision will be generated as a button in the UI.

Let’s look at the Decision code:

Decision takePhoto action('MainContext.takePhoto') label('Take Photo')

We have named the Decision takePhoto

action('MainContext.takePhoto'

The first part of this line of code tells Mat|r to look for the rules governing takePhoto in “MainContext”.

label('Take Photo')

The label with the value of ‘Take Photo’ is the text for the button in the UI generated by Decision. So the Decision takePhoto will generate a button in the UI that is labeled “Take Photo” that will perform the action defined by the rule in MainContext when the user clicks on the button.

You will note that a red x has appeared next to line 5 where we have written our Decision code. If you roll your cursor over the x you will get the error message – Error: takePhoto is not an existing rule in context MainContext. This is because we have defined the Decision but we have not yet defined the rule for the Decision. This we will take care of when we code the rules.

Now on to the second attribute

String myPhoto as Image

Here we have a String we have named myPhoto. The code “as Image” will cause Mat|r to generate an image component in the PhotoExperience layout (UI) using the path in the string >myPhoto

Next we are going to define the rules that govern the experience:

RuleContext MainContext {

      Rule takePhoto {

         PhotoExperience expData = broker.ui.getDataSource()

         MediaCameraConfigure mcc = MediaCameraConfigure()

         MediaFile photoData = broker.media.open(mcc)

         if (photoData != null) {

            expData.myPhoto = photoData.getURL()

      }

   }

}

Code definitions:
RuleContext is a container for rules in Mat|r|script.

First up in defining the rules is to add a RuleContext to put them in.

RuleContext MainContext {

Adds a RulesContext with the name MainContext. We have already specified in Decision that the rules for the Decision takePhoto would be in MainContext.

Rule takePhoto {

Create a rule inside MainContext and name it takePhoto.

code definitions:
Variable is a value that can change, depending on conditions or on information passed to the program. Variables are used to store information to be referenced and used by programs. In Mat|r you must declare what type of data a variable will store when you create it.

broker service in Mat|r|script a broker service allows an app to access native device or system services like the camera or GPS on a phone or to access built-in Mat|r functionality like IoT connections or cloud storage. Here is a list of the services currently available: http://matrproject.com/docs/eng/broker-services/

The rules need to know when the Take a Photo button is clicked in the PhotoExperience UI. So we are going to create a variable that will store information about the state of the UI.

PhotoExperience expData

Defines a variable named expData and specifies the data type as PhotoExperience.

Mat|r is a strongly typed language which means you must specify data type for every variable you create. PhotoExperience is a Model data type. In Mat|r, a Model is an experience and its auto-generated visual representation (UI). The second half of this line of code will specify where expData will get its data (the value it stores) from.

PhotoExperience expData = broker.ui.getDataSource()

broker.ui.getDataSource() is a broker service. The job of the broker service broker.ui.getDataSource() is to monitor the state of the UI of an Experience. In this case we are telling the broker service broker.ui.getDataSource() to watch the UI of PhotoExperience, and assign the data it returns from the UI to the variable expData. 

You don’t need to understand the complexities of how >broker.ui.getDataSource() works. All you need to know is, if your program needs to know what is going on in the UI of an Experience, broker.ui.getDataSource() can do that job for you.

You can call broker services with the reserved word “broker.”, followed by the namespace of the service you want to invoke. Here is a list of broker services: http://matrproject.com/docs/eng/broker-services/

Next we need to configure the camera.

MediaCameraConfigure mcc = MediaCameraConfigure()

This line of code creates an instance of a configuration model for the camera, i.e., front camera or back camera, flash on or not, We will store the configuration info in a variable we have named mcc so that the configuration can be passed to the broker service in the next line.

Now that we have a variable that lets us keep track of the UI, and have configured the camera let’s create a variable that will allow us to keep track of the photos the user is taking.

MediaFile photoData = broker.media.open(MediaCameraConfigure())

Code definitions:
MediaFile This data type allows the user to manage the location and content of a Media-type file that may be a photo or video stored in the device.

MediaCameraConfigure allows the user to manage and configure the access to the photo and video camera.

broker.media.open is a Mat|r broker service. It opens the camera with the options set up in the argument (See MediaCameraConfigure). When taking a photo or recording a video, it returns a MediaFile.

getURL() Address of the file system of the device where media files is stored.

MediaFile photoData

First we create a variable named photoDatawith the data type MediaFile.

Now just like in the previous line of code we are going to use a broker service to get the value for our variable. We are going to use the broker service broker.media.open which will open the camera with the camera options set in MediaCameraConfigure. Photo contains the location of the photo. So we take that information assign it to the variable photoData.

Then invoke the MediaFile method getURL(). The MediaFile method getURL() will lookup the location of the Image. Finally we will create some if / then logic, if this happens, do that.

if (photoData != null) { 

If the variable photoData is not null then it has MediaFile data in it which means the user took a photo.

expData.myPhoto = photoData.getURL() 

>expData contains the UI info, that a button was clicked and a photo taken.

Your code should now look like this:

Experience PhotoExperience {
   Decision takePhoto action('MainContext.takePhoto') label('Take a Photo')
String myPhoto as Image
}

RuleContext MainContext {

      Rule takePhoto {
         PhotoExperience expData = broker.ui.getDataSource()
         MediaCameraConfigure mcc = MediaCameraConfigure()
         MediaFile photoData = broker.media.open(mcc)
         if (photoData != null) {
            expData.myPhoto = photoData.getURL()
         }
   }

}

Congratulations! Your first app on Mat|r has been successfully created.

AAAA