This file is indexed.

/usr/share/doc/python-gtk2-tutorial/html/sec-DrawingAreaWidgetAndDrawing.html is in python-gtk2-tutorial 2.4-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>24.3. The DrawingArea Widget, And Drawing</title><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="PyGTK 2.0 Tutorial"><link rel="up" href="ch-Scribble.html" title="Chapter 24. Scribble, A Simple Example Drawing Program"><link rel="previous" href="sec-EventHandling.html" title="24.2. Event Handling"><link rel="next" href="ch-TipsForWritingPyGTKApplications.html" title="Chapter 25. Tips For Writing PyGTK Applications"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">24.3. The DrawingArea Widget, And Drawing</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="sec-EventHandling.html">Prev</a> </td><th width="60%" align="center">Chapter 24. Scribble, A Simple Example Drawing Program</th><td width="20%" align="right"> <a accesskey="n" href="ch-TipsForWritingPyGTKApplications.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec-DrawingAreaWidgetAndDrawing"></a>24.3. The DrawingArea Widget, And Drawing</h2></div></div><div></div></div><p>We now turn to the process of drawing on the screen. The widget
we use for this is the <tt class="classname">DrawingArea</tt> (see <a href="ch-DrawingArea.html" title="Chapter 12. Drawing Area">Chapter 12, <i>Drawing Area</i></a>) widget. A drawing area widget is
essentially an X window and nothing more. It is a blank canvas in which we
can draw whatever we like. A drawing area is created using the call:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  darea = gtk.DrawingArea()
</pre></td></tr></table><p>A default size for the widget can be specified by
calling:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  darea.set_size_request(<b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>)
</pre></td></tr></table><p>This default size can be overridden, as is true for all widgets,
by calling the <tt class="methodname">set_size_request</tt>() method, and that,
in turn, can be overridden if the user manually resizes the the window
containing the drawing area.</p><p>It should be noted that when we create a
<tt class="classname">DrawingArea</tt> widget, we are completely responsible for
drawing the contents. If our window is obscured then uncovered, we get an
exposure event and must redraw what was previously hidden.</p><p>Having to remember everything that was drawn on the screen so we
can properly redraw it can, to say the least, be a nuisance. In addition, it
can be visually distracting if portions of the window are cleared, then
redrawn step by step. The solution to this problem is to use an offscreen
backing pixmap. Instead of drawing directly to the screen, we draw to an
image stored in server memory but not displayed, then when the image changes
or new portions of the image are displayed, we copy the relevant portions
onto the screen.</p><p>To create an offscreen pixmap, we call the function:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  pixmap = gtk.gdk.Pixmap(<b class="parameter"><tt>window</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>, <b class="parameter"><tt>depth</tt></b>=-1)
</pre></td></tr></table><p>The <i class="parameter"><tt>window</tt></i> parameter specifies a
<tt class="classname">gtk.gdk.Window</tt> that this <i class="parameter"><tt>pixmap</tt></i> takes some of its
properties from.  <i class="parameter"><tt>width</tt></i> and
<i class="parameter"><tt>height</tt></i> specify the size of the
<i class="parameter"><tt>pixmap</tt></i>. <i class="parameter"><tt>depth</tt></i> specifies the
color depth, that is the number of bits per pixel, for the new window. If
the <i class="parameter"><tt>depth</tt></i> is specified as -1 or omitted, it will
match the depth of window.</p><p>We create the pixmap in our "configure_event" handler. This
event is generated whenever the window changes size, including when it is
originally created.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
   32   # Create a new backing pixmap of the appropriate size
   33   def configure_event(widget, event):
   34       global pixmap
   35
   36       x, y, width, height = widget.get_allocation()
   37       pixmap = gtk.gdk.Pixmap(widget.window, width, height)
   38       pixmap.draw_rectangle(widget.get_style().white_gc,
   39                             True, 0, 0, width, height)
   40
   41       return True
 </pre></td></tr></table><p>The call to <tt class="methodname">draw_rectangle</tt>() clears the
pixmap initially to white. We'll say more about that in a moment.</p><p>Our exposure event handler then simply copies the relevant
portion of the pixmap onto the drawing area (widget) using the
<tt class="methodname">draw_pixmap</tt>() method. (We determine the area we
need to redraw by using the <i class="parameter"><tt>event.area</tt></i> attribute of
the exposure event):</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
   43   # Redraw the screen from the backing pixmap
   44   def expose_event(widget, event):
   45       x , y, width, height = event.area
   46       widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
   47                                   pixmap, x, y, x, y, width, height)
   48       return False
</pre></td></tr></table><p>We've now seen how to keep the screen up to date with our
pixmap, but how do we actually draw interesting stuff on our pixmap? There
are a large number of calls in PyGTK for drawing on drawables. A drawable is
simply something that can be drawn upon. It can be a window, a pixmap, or a
bitmap (a black and white image). We've already seen two such calls above,
<tt class="methodname">draw_rectangle</tt>() and
<tt class="methodname">draw_pixmap</tt>(). The complete list is:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  drawable.draw_point(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>)

  drawable.draw_line(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>x1</tt></b>, <b class="parameter"><tt>y1</tt></b>, <b class="parameter"><tt>x2</tt></b>, <b class="parameter"><tt>y2</tt></b>)

  drawable.draw_rectangle(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>fill</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>)

  drawable.draw_arc(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>fill</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>, <b class="parameter"><tt>angle1</tt></b>, <b class="parameter"><tt>angle2</tt></b>)

  drawable.draw_polygon(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>fill</tt></b>, <b class="parameter"><tt>points</tt></b>)

  drawable.draw_drawable(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>src</tt></b>, <b class="parameter"><tt>xsrc</tt></b>, <b class="parameter"><tt>ysrc</tt></b>, <b class="parameter"><tt>xdest</tt></b>, <b class="parameter"><tt>ydest</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>)

  drawable.draw_points(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>points</tt></b>)

  drawable.draw_lines(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>points</tt></b>)

  drawable.draw_segments(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>segments</tt></b>)

  drawable.draw_rgb_image(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>, <b class="parameter"><tt>dither</tt></b>, <b class="parameter"><tt>buffer</tt></b>, <b class="parameter"><tt>rowstride</tt></b>)

  drawable.draw_rgb_32_image(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>, <b class="parameter"><tt>dither</tt></b>, <b class="parameter"><tt>buffer</tt></b>, <b class="parameter"><tt>rowstride</tt></b>)

  drawable.draw_gray_image(<b class="parameter"><tt>gc</tt></b>, <b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>, <b class="parameter"><tt>dither</tt></b>, <b class="parameter"><tt>buffer</tt></b>, <b class="parameter"><tt>rowstride</tt></b>)
</pre></td></tr></table><p>The drawing area methods are the same as the drawable drawing
methods so you can use the methods described in <a href="sec-DrawingMethods.html" title="12.2. Drawing Methods">Section 12.2, &#8220;Drawing Methods&#8221;</a> for further details on these
methods. These methods all share the same first arguments. The first
argument is a graphics context (<i class="parameter"><tt>gc</tt></i>).</p><p>A graphics context encapsulates information about things such as
foreground and background color and line width. PyGTK has a full set of
functions for creating and modifying graphics contexts, but to keep things
simple we'll just use predefined graphics contexts. See <a href="ch-DrawingArea.html#sec-GraphicsContext" title="12.1. Graphics Context">Section 12.1, &#8220;Graphics Context&#8221;</a> section for more information on
graphics contexts. Each widget has an associated style. (Which can be
modified in a <tt class="filename">gtkrc</tt> file, see <a href="ch-GtkRcFiles.html" title="Chapter 23. GTK's rc Files">Chapter 23, <i>GTK's rc Files</i></a>.) This, among other things, stores a number
of graphics contexts. Some examples of accessing these graphics contexts
are:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  widget.get_style().white_gc

  widget.get_style().black_gc

  widget.get_style().fg_gc[STATE_NORMAL]

  widget.get_style().bg_gc[STATE_PRELIGHT]
</pre></td></tr></table><p>The fields <i class="parameter"><tt>fg_gc</tt></i>, <i class="parameter"><tt>bg_gc</tt></i>,
<i class="parameter"><tt>dark_gc</tt></i>, and <i class="parameter"><tt>light_gc</tt></i> are indexed by a
parameter which can take on the values:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  STATE_NORMAL,
  STATE_ACTIVE,
  STATE_PRELIGHT,
  STATE_SELECTED,
  STATE_INSENSITIVE
</pre></td></tr></table><p>For instance, for <tt class="literal">STATE_SELECTED</tt> the default
foreground color is white and the default background color, dark
blue.</p><p>Our function <tt class="methodname">draw_brush</tt>(), which does the
actual drawing on the pixmap, is then:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
   50   # Draw a rectangle on the screen
   51   def draw_brush(widget, x, y):
   52       rect = (int(x-5), int(y-5), 10, 10)
   53       pixmap.draw_rectangle(widget.get_style().black_gc, True,
   54                             rect[0], rect[1], rect[2], rect[3])
   55       widget.queue_draw_area(rect[0], rect[1], rect[2], rect[3])
</pre></td></tr></table><p>After we draw the rectangle representing the brush onto the
pixmap, we call the function:</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  widget.queue_draw_area(<b class="parameter"><tt>x</tt></b>, <b class="parameter"><tt>y</tt></b>, <b class="parameter"><tt>width</tt></b>, <b class="parameter"><tt>height</tt></b>)
</pre></td></tr></table><p>which notifies X that the area given needs to be updated. X will
eventually generate an expose event (possibly combining the areas passed in
several calls to <tt class="methodname">draw</tt>()) which will cause our expose
event handler to copy the relevant portions to the screen.</p><p>We have now covered the entire drawing program except for a few
mundane details like creating the main window.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sec-EventHandling.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch-Scribble.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch-TipsForWritingPyGTKApplications.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">24.2. Event Handling </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 25. Tips For Writing PyGTK Applications</td></tr></table></div></body></html>