1: /*
  2:  * java-gnome, a UI library for writing GTK and GNOME programs from Java!
  3:  *
  4:  * Copyright © 2007-2010 Operational Dynamics Consulting, Pty Ltd and Others
  5:  *
  6:  * The code in this file, and the program it is a part of, is made available
  7:  * to you by its authors as open source software: you can redistribute it
  8:  * and/or modify it under the terms of the GNU General Public License version
  9:  * 2 ("GPL") as published by the Free Software Foundation.
 10:  *
 11:  * This program is distributed in the hope that it will be useful, but WITHOUT
 12:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13:  * FITNESS FOR A PARTICULAR PURPOSE. See the GPL for more details.
 14:  *
 15:  * You should have received a copy of the GPL along with this program. If not,
 16:  * see http://www.gnu.org/licenses/. The authors of this program may be
 17:  * contacted through http://java-gnome.sourceforge.net/.
 18:  */
 19: package cairo;
 20: 
 21: import org.freedesktop.cairo.Context;
 22: import org.freedesktop.cairo.LinearPattern;
 23: import org.freedesktop.cairo.Pattern;
 24: import org.freedesktop.cairo.RadialPattern;
 25: import org.gnome.gdk.Event;
 26: import org.gnome.gdk.EventExpose;
 27: import org.gnome.gdk.Rectangle;
 28: import org.gnome.gtk.DrawingArea;
 29: import org.gnome.gtk.Gtk;
 30: import org.gnome.gtk.Widget;
 31: import org.gnome.gtk.Window;
 32: 
 33: /**
 34:  * Exercise drawing with the Cairo API. If you are rendering a custom Widget
 35:  * or otherwise drawing stuff with Cairo that is to be presented by GTK, you
 36:  * are expected to do this in the Widget.ExposeEvent handler for that Widget.
 37:  * 
 38:  * @author Andrew Cowie
 39:  * @author Carl Worth
 40:  */
 41: /*
 42:  * TODO rename this once we actually draw something interesting!
 43:  */
 44: /*
 45:  * Gradient example from the Cairo Tutorial.
 46:  */
 47: public class ExampleDrawingInExposeEvent
 48: {
 49:     public static void main(String[] args) {
 50:         final Window w;
 51:         final DrawingArea d;
 52: 
 53:         Gtk.init(args);
 54: 
 55:         w = new Window();
 56:         w.setTitle("Expose");
 57:         w.setDefaultSize(150, 150);
 58: 
 59:         d = new DrawingArea();
 60:         w.add(d);
 61:         w.showAll();
 62: 
 63:         d.connect(new Widget.ExposeEvent() {
 64:             public boolean onExposeEvent(Widget source, EventExpose event) {
 65:                 final Context cr;
 66:                 final Rectangle rect;
 67:                 final Pattern linear, radial;
 68: 
 69:                 /*
 70:                  * Out of interest, where is this occuring?
 71:                  */
 72: 
 73:                 rect = event.getArea();
 74:                 System.out.println("Widget.ExposeEvent bounded by " + rect.getWidth() + "x"
 75:                         + rect.getHeight() + " at " + rect.getX() + "," + rect.getY());
 76: 
 77:                 /*
 78:                  * With that out of the way, we get to the heart of the
 79:                  * matter: creating a Cairo Context based on (and mapped to)
 80:                  * the Drawable underlying the Widget. The key here is that
 81:                  * the Widget is mapped unlike earlier when we were
 82:                  * constructing it. The first Widget.ExposeEvent does not
 83:                  * occur until after the Widget is realized; indeed, that is
 84:                  * when it is triggered.
 85:                  */
 86: 
 87:                 cr = new Context(event);
 88: 
 89:                 /*
 90:                  * Now, finally do some drawing:
 91:                  */
 92: 
 93:                 cr.setSource(1.0, 0.1, 0.0, 1.0);
 94:                 cr.moveTo(10, 40);
 95:                 cr.lineTo(120, 145);
 96:                 cr.stroke();
 97: 
 98:                 /*
 99:                  * If youre used to using RGB triplets, just normalize them to
100:                  * the 0.0 to 1.0 range by dividing by 255. It's all the same
101:                  * to Cairo, really.
102:                  */
103: 
104:                 cr.setSource(225 / 255.0, 148 / 255.0, 11 / 255.0, 1.0);
105:                 cr.rectangle(70, 70, 20, 40);
106:                 cr.fill();
107: 
108:                 /*
109:                  * Now a much more complicated example of drawing: a linear
110:                  * colour gradiant with a radial alpha mask.
111:                  */
112: 
113:                 linear = new LinearPattern(0, 0, 150, 150);
114:                 linear.addColorStopRGB(0.0, 0.0, 0.3, 0.8);
115:                 linear.addColorStopRGB(1.0, 0.0, 0.8, 0.3);
116: 
117:                 radial = new RadialPattern(75, 75, 15, 75, 75, 60);
118:                 radial.addColorStopRGBA(0, 0.0, 0.0, 0.0, 0.0);
119:                 radial.addColorStopRGBA(1, 0.0, 0.0, 0.0, 1.0);
120: 
121:                 cr.setSource(linear);
122:                 cr.mask(radial);
123: 
124:                 return true;
125:             }
126:         });
127: 
128:         /*
129:          * And that's it. Conclude with connecting the usual tear-down
130:          * handler, and then fire up the main loop.
131:          */
132: 
133:         w.connect(new Window.DeleteEvent() {
134:             public boolean onDeleteEvent(Widget source, Event event) {
135:                 Gtk.mainQuit();
136:                 return false;
137:             }
138:         });
139: 
140:         Gtk.main();
141:     }
142: }
143: