Keyboard (Android)

Die Ketai-library (wir verwenden momentan Gingerbread v9) liefert einige der Android-GUI-Elemente. Z.B. ein Keyboard und ein Pop-up (Achtung: key+"" macht aus dem Buchstaben key einen Text).

import ketai.ui.*;

void setup() {
  orientation(PORTRAIT);
  background(0);
}

void draw() {
}

void mousePressed() {
  KetaiKeyboard.toggle(this);
}

void keyPressed() {
  KetaiAlertDialog.popup(this, "Popup!", key+"");
}

Text und Typografie

Eine Variable für Schriften: PFont. Eine für Texte: String. Entweder Systemschriften verwenden... (über ihren Namen, Namen anzeigen lassen mit PFont.list())

println(PFont.list());

...oder (insbesondere auf dem Telefon) Schriftart im Data-Ordner ablegen (genau wie Bilder) und laden:

PFont f;
String s;

void setup() {
  orientation(PORTRAIT);
  background(0);
  s = "Bla bla.";
  f = createFont("HypatiaSansPro-Regular.otf", 32);
}

Schrift auswählen mit textFont(Variable, Größe), anzeigen mit text().

void draw() {
  background(0);
  fill(255);
  textFont(f, 128);
  textAlign(CENTER, CENTER);
  text(s, width/2, height/2);
}

Einzelne Buchstaben aus einem String herausgreifen mit charAt():

PFont f;
String s;

size(640,640);
background(0);
s = "abcdefghijklmnopqrstuvwxyz";
f = createFont("HypatiaSansPro-Regular.otf", 128);

background(0);
float x = 80;
float y = 80;
for (int i=0; i<s.length(); i++) {
  textFont(f, 128+random(-30,30));
  fill(random(60,255));
  textAlign(CENTER, CENTER);
  text(s.charAt(i), x, y);
  x = x + 80;
  if (x > width-80) {
    x = 80;
    y = y + 160;
  }
}

Keyboard und Text (Android)

In keyPressed den aktuellen key auf den Bildschirm zeichnen (auch interessant hier: colorMode).

import ketai.ui.*;
PFont f;

void setup() {
  orientation(PORTRAIT);
  background(0);
  f = createFont("HypatiaSansPro-Regular.otf", 128);
}

void draw() {
}

void mousePressed() {
  KetaiKeyboard.toggle(this);
}

void keyPressed() {
  textFont(f, 128+random(-30,30));
  colorMode(HSB);
  fill(random(255),random(255),random(255),random(255));
  textAlign(CENTER, CENTER);
  text(key+"", random(width), random(height));
}

Gesten: Pinch und Rotate

Ketai liefert KetaiGesture für Multitouch-Gesten. Zum Beispiel zur Manipulation eines SVG.

import android.view.MotionEvent;
import ketai.ui.*;

KetaiGesture gesture;
PShape svgbild;
float groesse;

void setup() {
  orientation(PORTRAIT);
  gesture = new KetaiGesture(this);
  svgbild = loadShape("fade.svg");
  groesse = 100;
}

void draw() {
  background(0);
  shapeMode(CORNER);
  shape(svgbild, width/2, height/2, groesse, groesse);
}

Jetzt die Zwei-Finger-Rotation zur Rotation des Bildes nehmen:

void onRotate(float x, float y, float ang) {
  svgbild.rotate(ang);
}

Und mit zwei Fingern skalieren/zoomen:

void onPinch(float x, float y, float d) {
  groesse = groesse + d;
}

(Für Infos zur besseren Kontrolle über Rotation/Zoom/Translation siehe den Abschnitt "Transform" in der Processing-Referenz)

Achtung: KetaiGesture benötigt noch eine Funktion, damit alles klappt:

public boolean surfaceTouchEvent(MotionEvent event) {
  super.surfaceTouchEvent(event);
  return gesture.surfaceTouchEvent(event);
}

Gesten: Flick/Swipe, kurzer und langer Touch

Ein Balken bewegt sich über den Bildschirm (mit der Geschwindigkeit vx), wird langsamer (vx = vx*0.9) und springt vom Bildschirmende zum Anfang und umgekehrt (if, else if).

import android.view.MotionEvent;
import ketai.ui.*;

KetaiGesture gesture;
float vx;
float xpos;

void setup() {
  orientation(LANDSCAPE);
  gesture = new KetaiGesture(this);
  vx = 0;
  xpos = width/2;
}

void draw() {
  background(0);
  stroke(200);
  strokeWeight(16);
  line(xpos,0,xpos,height);
  
  vx = vx*0.9;
  
  xpos = xpos + vx;
  if (xpos > width) {
    xpos = 0;
  } else if (xpos < 0) {
    xpos = width;
  }
}

Flick/Swipe beschleunigt den Balken (wenn von rechts nach links, muss die Geschwindigkeit umgedreht werden, if):

void onFlick(float x, float y, float px, float py, float v) {
  vx = v/20;
  if (x < px) {
    vx = -vx;
  }
}

Ein kurzer Touch hält den Balken an, ein langer setzt ihn dort hin, wo gedrückt wurde.

void onTap(float x, float y) {
  vx = 0;
}

void onLongPress(float x, float y) {
  xpos = x;
  vx = 0;
}
Und wieder: KetaiGesture benötigt noch eine Funktion, damit alles klappt:

public boolean surfaceTouchEvent(MotionEvent event) {
  super.surfaceTouchEvent(event);
  return gesture.surfaceTouchEvent(event);
}

Exkurs: 2D-Transformationen

Processing bietet eine Reihe von Transformationsmöglichkeiten für das Zeichnen in 2D und 3D. Diese Operationen betreffen immer die gesamte Zeichenfläche! D.h. jede Transformation bewegt die gesamte Zeichenfläche und betrifft alles was anschließend gezeichnet wird.

translate(...) verschiebt die Zeichenfläche in x- und y-Richtung...

size(400,400);
background(255);

rectMode(CORNER);

noStroke();
fill(128,0,0,128);
rect(10,10,200,200);

translate(60,100);

fill(0,0,128,128);
rect(10,10,200,200);

...rotate(...) rotiert die Zeichenfläche um den Punkt (0,0) (Achtung: radians/degrees)...

size(400,400);
background(255);

rectMode(CORNER);

noStroke();
fill(128,0,0,128);
rect(10,10,200,200);

rotate(radians(10));

fill(0,0,128,128);
rect(10,10,200,200);

...und scale(...) skaliert die Zeichenfläche.

size(400,400);
background(255);

rectMode(CORNER);

noStroke();
fill(128,0,0,128);
rect(10,10,200,200);

scale(1.5);

fill(0,0,128,128);
rect(10,10,200,200);

Beispiel: in die Bildschirmmitte verschieben, da dann um die Mitte rotieren und zentriertes Rechteck zeichnen, skalieren, rotieren, erneut zeichnen.

size(400,400);
background(255);
noStroke();

rectMode(CENTER);

translate(width/2,height/2);

fill(128,0,0,128);
rect(0,0,200,200);

rotate(radians(45));

fill(0,0,128,128);
rect(0,0,200,200);

scale(0.5);
rotate(radians(10));

fill(0,0,128,128);
rect(0,0,200,200);

Transformationen zurücksetzen: pushMatrix(...) und popMatrix(...)

size(400,400);
background(255);
noStroke();

rectMode(CENTER);

translate(width/2,height/2);

pushMatrix();
for (int i=0; i<9; i++) {
  rotate(radians(10));
  fill(128,0,0,128);
  rect(0,0,200,200);
}
popMatrix();

noFill();
stroke(0);
rect(0,0,300,300);

Tranformationen interaktiv: Variable zum Merken des Drehwinkels, reagieren auf Tastatur.

float winkel = 0;

void setup() {
  size(400,400);
}

void draw() {
  background(255);  
  noStroke();
  rectMode(CENTER);
  translate(width/2,height/2);
  rotate(radians(winkel));
  fill(128,0,0,128);
  rect(0,0,200,200);
}

void keyPressed() {
  if (key==CODED) {
    if (keyCode==LEFT) {
      winkel--;
    } else if (keyCode==RIGHT) {
      winkel++;
    }
  }
}