Processing: Sketches – Your Multi-Programs

When you start Processing, you get an editor with a sketch name. You will probably want another name for your program, a name that means something. So, to change the name generated by the tool, you choose file->save as. Choose a name, and the tool will create a folder with that name, and a file named <name>.pde.

When you run your sketch – by clicking the button with the triange or selecting ‘sketch->Run …’ (Run In Browser, Run on Device, Run In Emulator, Run, etc. Depending on the mode) – Processing will parse the ‘.pde’ files and the program used for running will create an instance each time you run it.

Setup and Draw

If you want have things to do upon initiation of your program, define a function named ‘void setup()‘.  To size your canvas call size(width, height). It is recommended to use ‘size’ only once in the setup function, and the whole sketch. A setup command is not called in run time. It is recommended to set the frame rate inside the setup function by calling ‘frameRate(rate)‘, the rate is the number of time the function ‘draw()‘ is supposed to be call every second. If you want an action to take place each time a frame changes, write a “draw” function in one of  your ‘.pde’ files.

More Than Just Pure Processing

Sometimes, pure Processing is not enough for your application. For example, sound functions do not exist in pure Processing. There are libraries, such as Maxim,  that extend Processing.

Another reason to use more than pure Processing is will to use native widgets (HTML elements, Android Menus & Dialogs, etc.). In pure Processing, you would have to draw the button and detect in the ‘mouseClicked‘ function if the mouse pointer is inside the button.

Here’s a little video example of using the android menu to change the number of polygon sides:

In addition, I’ve created a Javascript module, and added buttons to the HTML page displayed when running in Javascript mode.

The following sections will explain how to do it.

 The Common Part: Just Draw a Polygon

The sommon part that draws the polygon is found in a ‘.pde’ file in the ‘polygon’ sketch directory. The function ‘draw’ detects changes in the global variable n, the number of sides.

The functions ‘translate’ and ‘rotate’ make drawing rotated shapes and lines easier.

In addition, the module contains a call to a function named ‘alert’. This function exists in Javascript, so I’ve made another in the Android module using Toasts.

Following is the code:

// This program draws a regular polygon with n sides.
int n;
float halfVertexAngle; // Will be used for moving from the center
                      // of the sreen to a vertex of the polygon.
                                          
float rotateAngle;     

void set_no_of_sides(int inputN){
  if (inputN < 3){
    alert("Polygons must have at least 3 sides. Try again");
    return;
  }
  n=inputN;
  halfVertexAngle = radians(180) / n; 
  rotateAngle = radians(360./n);
}

void setup(){
  //size(640,480);
  set_no_of_sides(8);
  background(0xffffff00);
  strokeWeight(1);
}

void draw(){
    background(0xffffff00);

  // Center coordinates of the screen and circumbscribed circle.

  int centerX = width / 2;
  int centerY = height / 2;
  
  
  float radius = min(width / 2, height/2);  // The radius of the circumscribed circle.
 
  // Use the cosine theorem to find the length of a side. 
  float side = sqrt(2 * radius * radius * (1 - cos(2 * halfVertexAngle)));
  
  translate(centerX, centerY);  // Move the origin of axes to the center of the screen.
  rotate (-halfVertexAngle);    // Rotate the axes to find the first vertex without
                                // dealing with trigonometry.
  translate(0, radius);
  rotate(halfVertexAngle);      // Rotate back to make the first side horizontal.
  
  for (int i=0; i<n; i ++){
    line(0,0,-side,0);
    translate(-side,0);
    rotate(rotateAngle);
  }
}

The Android Module

I found that in my Linux system Android files are created in the ‘/tmp’ directory. Processing Android mode generates an extension of the class PApplet from your pde files. The good news is that PApplet extends the android Activity class, which makes adding event handlers easy.

Additional functions to a class extending PApplet should be written in a separate pde file. Following is the extension’s code:

import android.os.Bundle;
import android.widget.Toast;
import android.view.Menu;
import android.view.MenuItem;
import android.app.AlertDialog;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.content.DialogInterface;

AlertDialog.Builder alertDialog=null;

public void alert(String text){
  Toast toast=Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
  toast.show();
}

public void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  
}

 public boolean onCreateOptionsMenu (Menu menu){
   super.onCreateOptionsMenu (menu);
   menu.add(Menu.NONE, 37, Menu.NONE, "Change Number of sides");
   return true;
 }
 
 private void createAlertDialog(){
     // Create a dialog to change the number of polygon sides.
  alertDialog = new AlertDialog.Builder(this);
  alertDialog.setTitle("Polygon Settings");
  alertDialog.setMessage("Enter number of polygon sides:");
  final EditText input = new EditText(polygon.this);
  LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.MATCH_PARENT,
                                    LinearLayout.LayoutParams.MATCH_PARENT);
  input.setLayoutParams(lp);
  alertDialog.setView(input);
  alertDialog.setPositiveButton("Accept",
    new DialogInterface.OnClickListener(){
      public void onClick(DialogInterface dialog, int which){
        int numberParsed;
        try {
          numberParsed = Integer.parseInt(input.getText().toString());
          set_no_of_sides(numberParsed);
        } catch (NumberFormatException ex){
          alert("Not an integer. Try again.");
        }
      }
    });

  alertDialog.setNegativeButton("Cancel",
    new DialogInterface.OnClickListener(){
      public void onClick(DialogInterface dialog, int which){
      }
    });

 }
 
 public boolean onMenuItemSelected(int featureId, MenuItem menuitem){
   super.onMenuItemSelected(featureId, menuitem);
   switch (menuitem.getItemId()){
     case 37:
       createAlertDialog();
       alertDialog.show();
       break;
     default:
       break;
   }
   return true;
 }

Notes:

  • If you have an Android module, but you want to run in another mode, renaming the Android mode’s pde file with a ‘.bak’ extension is recommended.
  • If the Android module is not installed, you can install it from a Processing editor window, by selecting <mode button> -> Add more…

Javascript Functions & Changes to the HTML Page

You can change the appearance of your output HTML page by editing the file <sketch-name>/template/template.html . If the file and directory do not exist yet, you can create them by choosing “Javascript->Start Custom Template”. If they do exist use “Javascript-.Show Custom Template”.

For example, I’ve added a button in the HTML template as follows:

<input type="button" value="Change Number of Sides" onclick="get_no_of_sides(this);" />

In addition, I’ve added an ‘onload’ event to change the size of the canvas after the polygon object is created. This function works fine in my favorite browser, Firefox. Fortunately, from ‘.js’ module one can call ‘size’ to resize the canvas:

    <body onload="new_size(640, 480);">

From this page you can learn about accessing Processing from Javascript.

Following is my javascript code defined in ‘js_functions.js’:

function new_size(w, h){
  var divElement=document.getElementById('content');
  divElement.addEventListener("DOMSubtreeModified", function(event, func){
    if (window.Processing.getInstanceById("polygon")){
      divElement.removeEventListener("DOMSubtreeModified", arguments.callee);
      divElement.style.width = w + "px";
      window.Processing.getInstanceById("polygon").size(w,h);
    }
  });

function get_no_of_sides(obj){

  var k=prompt("How many sides?");
  var num=Number(k);
  if (isNaN(num) || num != parseInt(k)){
    alert("Please type an integer");
    return;
  }

  this.Processing.getInstanceById('polygon').set_no_of_sides(num);
}

Now, when you run your application, the product will be found in ‘<sketch-name>/web-export’.
Learn more about Javascript modules here.

Advertisement