<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>learning python &#187; TextWidget</title>
	<atom:link href="http://www.learningpython.com/category/python/textwidget/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Mon, 26 Apr 2010 01:21:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TextWidget 0.1</title>
		<link>http://www.learningpython.com/2008/09/21/textwidget-01/</link>
		<comments>http://www.learningpython.com/2008/09/21/textwidget-01/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 21:41:50 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[TextWidget]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=99</guid>
		<description><![CDATA[
			
				
			
		
It&#8217;s been a long time since I worked on TextWidget at all, but since someone posted a question about it I decided to fix the issue and re-release the source. But since I didn&#8217;t want to simply update the blog post I decided to give the project a proper home on google code: http://code.google.com/p/textwidget/
The project [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F09%2F21%2Ftextwidget-01%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F09%2F21%2Ftextwidget-01%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>It&#8217;s been a long time since I worked on <a href="http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/">TextWidget</a> at all, but since someone posted a question about it I decided to fix the issue and re-release the source. But since I didn&#8217;t want to simply update the blog post I decided to give the project a proper home on google code: <a href="http://code.google.com/p/textwidget/">http://code.google.com/p/textwidget/</a></p>
<p>The project is really simple and meant as an easy way for you to create &#8220;text buttons&#8221; for your PyGame projects.  It&#8217;s not meant to be the definitive way to do this, just a simple solution for people that just want to drop a class in and have working &#8220;text buttons&#8221;. It&#8217;s LGPL so you can use it in whatever way you want. If you do decide to use it please drop me an email and let me know.</p>
<p>For more information on how to use the project please take a look at the initial <a href="http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/">blog post</a>.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2008/09/21/textwidget-01/&title=TextWidget 0.1&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/09/21/textwidget-01/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TextWidget &#8211; A simple text class for PyGame</title>
		<link>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/</link>
		<comments>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/#comments</comments>
		<pubDate>Thu, 14 Dec 2006 03:47:28 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[TextWidget]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=49</guid>
		<description><![CDATA[
			
				
			
		
Introduction
All right, this is just a little tutorial about working with text in pygame.  Now, this isn&#8217;t the only way to work with text, there are many other methods to do this, in fact much of the time you&#8217;ll probably end up using images for interactive text.  So this is mainly meant to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F12%2F13%2Ftextwidget-a-simple-text-class-for-pygame%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F12%2F13%2Ftextwidget-a-simple-text-class-for-pygame%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<h2>Introduction</h2>
<p>All right, this is just a little tutorial about working with text in pygame.  Now, this isn&#8217;t the only way to work with text, there are many other methods to do this, in fact much of the time you&#8217;ll probably end up using images for interactive text.  So this is mainly meant to serve as a informative guide to using the text features in PyGame, and how you <em>might</em> want to implement them.</p>
<p>The TextWidget object discussed in this tutorial can be used to make something that looks like this (but you&#8217;d probably want to use better looking colours):</p>
<p><embed src="http://www.learningpython.com/flash/textwidget.swf" width="320" height="240" play="true" loop="True" quality="low" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"><br />
</embed></p>
<p>The full source and necessary files for this tutorial can be downloaded <a href="http://www.learningpython.com/sources/TextWidget.tar.gz">here</a>.</p>
<p>So, in order to make this easy to use and very reusable we&#8217;re going to create a class called TextWidget in a file called TextWidget.py.  The top of the file is full of the standard python initialization:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#! /usr/bin/env python

</span><span class="hl-reserved">import </span><span class="hl-identifier">pygame

TEXT_WIDGET_CLICK</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals</span><span class="hl-default">.</span><span class="hl-identifier">USEREVENT</span><span class="hl-default"> + </span><span class="hl-number">1</span></pre></div></div>
<p>We import pygame and then we set a define TEXT_WIDGET_CLICK , which will be used later on as the event type when the TextWidget is clicked on.</p>
<p>The next thing to do is define the actual class:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>Now the astute among you will recognize that this is a &#8220;new-style&#8221; python class (i.e. it&#8217;s base class is the object class) rather then a classic class.  I did this for two reasons:</p>
<ol>
<li>I wanted to be able to control what happens when people set values in the class.  So, for example, if you set the size of the font to be something, I wanted the display to automatically adjust to reflect the new size.</li>
<li>I haven&#8217;t really used new-style classes before so I thought I&#8217;d try them out.</li>
</ol>
<p><strong>Note:</strong> If you are unfamiliar with properties or new-style classes you might want to give this a read: </p>
<ul>
<li><a href="http://www.python.org/download/releases/2.2.3/descrintro">Unifying types and classes in Python 2.2</a></li>
<li><a href="http://www.geocities.com/foetsch/python/new_style_classes.htm#property">Introduction To New-Style Classes In Python</a></li>
</ul>
<p><span id="more-49"></span></p>
<p>As a result of number one above I&#8217;m going to use <a href="http://www.python.org/download/releases/2.2.3/descrintro/#property">properties</a> for those values that I want to perform some &#8220;automatic processing&#8221; when their values changes.</p>
<p>The properties that I am going to define are as follows:</p>
<ul>
<li>text &#8211; The string of text that the TextWidget will display.</li>
<li>colour &#8211; The colour that the text will be rendered in.</li>
<li>size &#8211; The size of the font.</li>
<li>font_filename &#8211; The filename of the font to use for the text (probably something returned by <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.get_fonts">pygame.font.get_fonts</a> or <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.match_font">pygame.font.match_font</a>.</li>
<li>highlight &#8211; A boolean, whether the font is highlighted or not. (i.e. whether the mouse is over the TextWidget.</li>
<li>highlight_cursor &#8211; A boolean that controls whether or not to show a hand cursor when the TextWidget is in highlight mode.  If the TextWidget is not supposed to be interactive you should set this to False.</li>
</ul>
<p>There are also a few other important members of the class, but since they are not python properties I have listed them separately:</p>
<ul>
<li>__hand &#8211; A hand cursor, which can optionally by displayed when the cursor hovers over the text.</li>
<li>dirty &#8211; A boolean, that lets the TextWidget know whether or not it needs to draw.  If dirty = False it will not draw, if dirty = True it will draw.</li>
<li>bold_rect &#8211; pygame.Rect &#8211; A rectangle that is equal to the size of the highlighted text.  It is used so that when we move from highlighted to non-highlighted text all of the text is erased.  Otherwise if we just drew updated the normal rectangle, all of the highlighted text that was outside of it would not be redrawn.</li>
<li>rect – pygame.Rect – The Rectangle where the text will be drawn.  Use this to position your text, but its height and width will always be controlled by the text and the font.</li>
<li>highlight_increase &#8211; Boolean whether or not the text should increase in size when the cursor is over it.  If the text is &#8220;non-interactive&#8221; then this should be False.</li>
<li>tracking &#8211; Boolean whether or not the TextWidget is tracking a mouse click.  Used so that we can tell whether or not a true &#8220;click&#8221; has occurred.  A true click is one where both the mouse-down and mouse-up events occur on the TextWidget.</li>
</ul>
<p>To hopefully make the functionality of the TextWidget a bit clearer here is some non-highlighted text and then some highlighted text:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/text_01.png" alt="Python pygame text" border="0" /></p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/text_02.png" alt="Python pygame text" border="0" /></p>
<h2>The Code</h2>
<p>Now we get to the heart of the actual python\PyGame code, where we actually create a working TextWidget object.</p>
<p>So we&#8217;ll start off at the top of the file and then work out way downwards in a linear manner.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is a helper class for handling text in PyGame.  It performs 
    some basic highlighting and tells you when the text has been clicked.
    This is just one of the many ways to handle your text.
    This is a new-style class and I am somewhat new to them so hopefully it 
    all works.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Hand Cursor
    </span><span class="hl-identifier">__hand_cursor_string</span><span class="hl-default"> = </span><span class="hl-brackets">(
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     XX         </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..XXXXX    </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X..X.XX  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string"> XX X..X..X.X.X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">X..XX.........X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">X...X.........X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string"> X.....X.X.X..X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">  X....X.X.X..X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">  X....X.X.X.X  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">   X...X.X.X.X  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X.......X   </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     X....X.X   </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     XXXXX XX   </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">__hcurs</span><span class="hl-default">, </span><span class="hl-identifier">__hmask</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">cursors</span><span class="hl-default">.</span><span class="hl-builtin">compile</span><span class="hl-brackets">(</span><span class="hl-identifier">__hand_cursor_string</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">.</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">X</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">__hand</span><span class="hl-default"> = </span><span class="hl-brackets">((</span><span class="hl-number">16</span><span class="hl-code">, </span><span class="hl-number">16</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">__hcurs</span><span class="hl-code">, </span><span class="hl-identifier">__hmask</span><span class="hl-brackets">)</span></pre></div></div>
<p>The above code is where we create the hand cursor that we will use if the person turns on the highlight_cursor.  We first define what the cursor will look like as explained in the <a href="http://www.pygame.org/docs/ref/cursors.html#pygame.cursors.compile">PyGame cursor documentation</a>.</p>
<p>The next step is to create all of our properties, now this code may seem a bit complicated, especially since it deals with functions that we have not created yet, but as I explain it, it could become clearer and clearer.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Text
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_text</span><span class="hl-code"> != </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text</span><span class="hl-default"> = </span><span class="hl-identifier">text
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()
</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_text</span><span class="hl-code">, </span><span class="hl-identifier">__set_text</span><span class="hl-brackets">)</span></pre></div></div>
<p>The above code creates the TextWidget.text property.  The __get_text() function is used to get the text property which is represented by the __m_text variable, and the __set_text() function is the function that is called when you want to set the value of the text property.</p>
<p>What you will notice about the __set_text() function is that it first tests to see if the text that we are setting (text) is any different then the current text (__m_text) if it isn&#8217;t any different we don&#8217;t do anything.  </p>
<p>However if it is different we set __m_text and we call update_surface().  update_surface() is a member function that I will explain in more detail later, but for now all you need to know is that it updates what the widget will display.  So since we changed the text we want the widget to update and display the new text.</p>
<p>You can probably see why I wanted to use new-style classes and properties now.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Colour
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_colour</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_colour</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">colour</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_colour</span><span class="hl-code"> != </span><span class="hl-identifier">colour</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour</span><span class="hl-default"> = </span><span class="hl-identifier">colour
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()
</span><span class="hl-identifier">colour</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_colour</span><span class="hl-code">, </span><span class="hl-identifier">__set_colour</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next is the colour property, as you can see it&#8217;s basically identical to the text property, so I won&#8217;t bother explaining it.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Size
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_size</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_size</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_size</span><span class="hl-code"> != </span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size</span><span class="hl-default"> = </span><span class="hl-identifier">size
        self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_size</span><span class="hl-code">, </span><span class="hl-identifier">__set_size</span><span class="hl-brackets">)</span></pre></div></div>
<p>The next property is the size property, which controls the size of the font.  Now this is slightly different in that it calls the create_font() function rather then the update_surface() function that the text and the colour property did. </p>
<p>The reason for this is that the size property is used in the creation of the actual font object that is used to update the surface which is eventually drawn to the screen.  As with the update_surface() function I will explain the create_font() function later.  Properties that call create_font() do not have to call update_surface() because create_font() calls update_surface().</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Font Filename
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_font_filename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_font_filename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">font_filename</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-code"> != </span><span class="hl-identifier">font_filename</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-default"> = </span><span class="hl-identifier">font_filename
        self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">font_filename</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_font_filename</span><span class="hl-code">, </span><span class="hl-identifier">__set_font_filename</span><span class="hl-brackets">)</span></pre></div></div>
<p>Then we have the font_filename property that represents the full path to the font file.  So if that changes we need to recreate the font in order to display the text using the correct font.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Highlight
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_highlight</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_highlight</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">not</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-code"> == </span><span class="hl-identifier">highlight</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-comment">#Save the bold_rect
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect
        self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-default"> = </span><span class="hl-identifier">highlight
        </span><span class="hl-comment">#update the cursor
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">()
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> += </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> -= </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase
        if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight_increase</span><span class="hl-code"> == </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_highlight</span><span class="hl-code">, </span><span class="hl-identifier">__set_highlight</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next we have the highlight property, the highlight property is a boolean property that controls whether or not the TextWidget should display &#8220;highlighted&#8221; or not.  When a TextWidget is highlighted the font will be displayed in bold, have its size increased by a specific amount, and (if enabled) the hand cursor will be displayed.</p>
<p>So now since the __get_highlight() function is the same as all of the others, I&#8217;ll just explain the __set_highlight() function.</p>
<p>First we check to see that the new value is different then the old value.  We do this so that we don&#8217;t waste time with useless font creations or extra draws.  </p>
<p>Then we check to see if the current state of the TextWidget is highlighted, because if it is, we know that it is about to go back to normal (because of the first if.)  If that is the case we save the current rect as bold_rect so that the next time we draw we will want bold_rect to be drawn so that all of the previous highlighted text is overwritten.</p>
<p>Then we set the internal highlight value and call the update_cursor() function which will decide whether or not the cursor should be a hand or the default arrow.  </p>
<p>Then we set the size of the font depending on whether or not the highlight state has been turned on.  If it is we increase the size, and if it is not we decrease the size back down to normal.  </p>
<p>Since increasing or decreasing the size will call create_font() we only need to call create_font() if self.highlight_increase is equal to zero, since in that case the value of the size property will not change and the font will not be created. </p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Show Highlight Cursor
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_highlight_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_highlight_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-code"> != </span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-default"> = </span><span class="hl-identifier">highlight_cursor
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">()
</span><span class="hl-identifier">highlight_cursor</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_highlight_cursor</span><span class="hl-code">, </span><span class="hl-identifier">__set_highlight_cursor</span><span class="hl-brackets">)</span></pre></div></div>
<p>Lastly we have the highlight_cursor property, which is a boolean property that  controls whether or not the highlight (hand) cursor should be displayed.  If you have made it this far and have understood the rest of the properties then understanding this property shouldn&#8217;t be too difficult.  Basically it simply checks to see if we should update the property, and if so it updates it and then calls update_cursor() just in case we need the cursor to update right now.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">colour</span><span class="hl-code">=</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">size</span><span class="hl-code">=</span><span class="hl-number">32</span><span class="hl-code">
             , </span><span class="hl-identifier">highlight_increase</span><span class="hl-code"> = </span><span class="hl-number">20</span><span class="hl-code">, </span><span class="hl-identifier">font_filename</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-code">
             , </span><span class="hl-identifier">show_highlight_cursor</span><span class="hl-code"> = </span><span class="hl-reserved">True</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize the TextWidget
    @param text = &quot;&quot; - string - The text for the text widget
    @param colour = (0,0,0) - The colour of the text
    @param size = 32 - number - The size of the text
    @param highlight_increate - number - How large do we want the
    text to grow when it is highlighted?
    @param font_filename = None - string the patht to the font file
    to use, None to use the default pygame font.
    @param show_highlight_cursor = True - boolean - Whether or not to change
    the cursor when the text is highlighted.  The cursor will turn into
    a hand if this is true.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-comment">#inits
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase</span><span class="hl-default"> = </span><span class="hl-identifier">highlight_increase
    self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    
    </span><span class="hl-comment">#property inits
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">text
    self</span><span class="hl-default">.</span><span class="hl-identifier">colour</span><span class="hl-default"> = </span><span class="hl-identifier">colour
    self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-identifier">size
    self</span><span class="hl-default">.</span><span class="hl-identifier">font_filename</span><span class="hl-default"> = </span><span class="hl-identifier">font_filename
    self</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_cursor</span><span class="hl-default"> = </span><span class="hl-identifier">show_highlight_cursor
    
    self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now we actually start using the class the first thing we do is code the __init__() function in which we initialize all of our data members and properties, and then create the font at the end.  This may result in the font being create twice sometimes but it will only happen once when the Widget is created, and it makes sure that the font is always created.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">mouse</span><span class="hl-default">.</span><span class="hl-identifier">set_cursor</span><span class="hl-brackets">(</span><span class="hl-code">*</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__hand</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">mouse</span><span class="hl-default">.</span><span class="hl-identifier">set_cursor</span><span class="hl-brackets">(</span><span class="hl-code">*</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">cursors</span><span class="hl-code">.</span><span class="hl-identifier">arrow</span><span class="hl-brackets">)</span></pre></div></div>
<p>Here is the update_cursor() function, it&#8217;s pretty straight forward.  First we check whether or not we are supposed to change the cursor at all.  If we are then we check to see if we are highlighted or not.  If we are highlighted then we use the hand cursor that we created above, and if we are not highlighted we use the built-in pygame arrow cursor.</p>
<h2>Drawing and Fonts</h2>
<p>Now we finally get to drawing and the font creation that we talked about earlier.  The first thing to do is to create our font:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_font</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create the internal font, using the current settings
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">Font</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">font_filename</span><span class="hl-code">
                                 , </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">size</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()</span></pre></div></div>
<p>As you can see this function really is pretty simple, all we need to make sure that we have is a size for the font.  Then we create the font using <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.Font">pygame.font.Font()</a>  We don&#8217;t care if self.font_filename is None since if it is None, then the default font will be loaded. </p>
<p>After the font has been created we call update_surface():</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">update_surface</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Update the current surface, basically render the
    text using the current settings.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_font</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default">.</span><span class="hl-identifier">set_bold</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default">.</span><span class="hl-identifier">render</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">
                                        , </span><span class="hl-reserved">True</span><span class="hl-code">
                                        , </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">colour</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-comment"># Used the current rects center point
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">(</span><span class="hl-identifier">center</span><span class="hl-code">=</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">center</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span></pre></div></div>
<p>In update_surfacte() we first make sure that our font (__m_font) exists, since if it does not then there is no point in creating any surface.  Then we set the font&#8217;s bold setting <a href="http://www.pygame.org/docs/ref/font.html#Font.set_bold">Font.set_bold()</a> function and controlled by the highlight property.</p>
<p>Then we render the font onto a <a href="http://www.pygame.org/docs/ref/surface.html#pygame.Surface">pygame.surface</a> using the <a href="http://www.pygame.org/docs/ref/font.html#Font.render">Font.render()</a> function and our current text and colour.  We also make sure that the font is anti-aliased by passing True as the second parameter.</p>
<p>Then we set self.Dirty to True to make sure that the next time through the draw loop the new surface gets displayed.  </p>
<p>The last thing we do in the function is move our text into the correct location.  If self.rect has been specified then we move the image into that position and set our rect, otherwise we initialize self.rect to be be surfaces rectangle.  </p>
<p>self.rect must eventually be move into some position because <a href="http://www.pygame.org/docs/ref/surface.html#Surface.get_rect">Surface.get_rect()</a> always returns a rectangle that starts at 0,0.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">screen</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw yourself text widget
    @param screen - pygame.Surface - The surface that we will draw to
    @returns - pygame.rect - If drawing has occurred this is the 
    rect that we drew to.  None if no drawing has occurred.</span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">image</span><span class="hl-brackets">)  </span><span class="hl-identifier">and  </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">) </span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">dirty</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">bold_rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">We may need to overwrite the bold text size
            This gets rid of leftover text when moving from 
            bold text to non-bold text.
            </span><span class="hl-quotes">&quot;&quot;&quot;
            </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">Rect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">bold_rect</span><span class="hl-brackets">)
            </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set to None, since we only need to do this
            once.</span><span class="hl-quotes">&quot;&quot;&quot;
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
        else</span><span class="hl-default">:
            </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect
        </span><span class="hl-comment">#Draw the text
        </span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">image</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Dirty no more
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">False

    return </span><span class="hl-identifier">rect_return</span></pre></div></div>
<p>Finally we get to the draw code, and thankfully it&#8217;s pretty simple.  The draw() function take a <a href="http://www.pygame.org/docs/ref/surface.html">pygame.Surface</a> as the only parameter, this is the surface that we will be drawing to, probably the main surface in your game or application.  The draw function will also return a  <a href="http://www.pygame.org/docs/ref/rect.html">pygame.Rect</a> object (or None) which represents the area of the surface that needs to be updated (or not).</p>
<p>The first thing we do in the function is make sure that we actually have something to draw.  We check our rectangle (self.tect) and our surface (self.image) to make sure that everything has been initialized, and then we check self.dirty to see if we <em>should</em> draw anything. </p>
<p>Then we check to see if self.bold_rect is valid, if it is we return it as the rectangle to update and invalidate the bold_rect, since it only needed once, when moving from highlighted to non-highlighted). If self.bold_rect is not valid then we will return self.rect as the rectangle to update.</p>
<p>Then we <a href="http://www.pygame.org/docs/ref/surface.html#Surface.blit">blit</a> our text to the screen (which is stored in self.image as a pygame.Surface object) and set self.dirty to False so that we do not needlessly draw in the future.</p>
<h2>Events</h2>
<p>If you remember way back at the beginning of this tutorial we create a define for a future event that would be fired when the TextWidget was clicked on:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals</span><span class="hl-default">.</span><span class="hl-identifier">USEREVENT</span><span class="hl-default"> + </span><span class="hl-number">1</span></pre></div></div>
<p>Now is where we use it and let the main class know when a TextWidget has been clicked.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires.
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Check for collision
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">True</span></pre></div></div>
<p>First we have the on_mouse_button_down() function, this should be called by your main application during the event loop.  If you come across a MOUSEBUTTONDOWN event, then you should pass it to all of your TextWidget objects, or at least the TextWidgets that you want to be interactive.</p>
<p>All this function does is check to see if the mouse button down event occurred within the TextWidgets rect, if it did, self.Tracking is set to True to let the TextWidget know that it is “tracking” or listening for the MOUSEBUTTONUP event to complete the click.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires.
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Check for collision
    </span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">tracking</span><span class="hl-brackets">) </span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)))</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-comment">#Not Tracking anymore
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False</span></pre></div></div>
<p>Next we have the on_mouse_button_up function which called by your main application for all of your interactive TextWidget objects when the MOUSEBUTTONDOWN event is found.  </p>
<p>This function is very simple, it first checks to see if we are currently tracking, if we are then we check to see if the event has occurred within the TextWidget&#8217;s rect.  If it has we call self.one_mouse_click() and pass it the event.</p>
<p>Then we set self.tracking to False, since whatever happened we are no longer tracking.  Now if you don&#8217;t fully understand what the self.tracking boolean does, it simply makes sure that the TextWidget behaves like a standard button, which means that it only registers MOUSEBUTTONUP events as a &#8220;click&#8221; if the MOUSEBUTTONDOWN also occurred within the buttons rectangle.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_click</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires, and the text widget
    has been clicked on.  You can either let
    this post the event (default) or you can override this
    function call in your app.
    ie. myTextWidget.on_mouse_click = my_click_handler
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Create the TEXT_WIDGET_CLICK event
    </span><span class="hl-identifier">event_attrib</span><span class="hl-default"> = {}
    </span><span class="hl-identifier">event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">button</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">button
    event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">pos</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">pos
    event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">text_widget</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">self
    e</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">Event</span><span class="hl-brackets">(</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-code">, </span><span class="hl-identifier">event_attrib</span><span class="hl-brackets">)
    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">)</span></pre></div></div>
<p>Finally in our event handling we have the on_mouse_click() function.  By default this function will <a href="http://www.pygame.org/docs/ref/event.html#pygame.event.post">post</a> a TEXT_WIDGET_CLICK event to the PyGame event queue which you can handle in whichever manner you like.</p>
<p>The event has the following attributes:</p>
<ul>
<li>button &#8211; The button of the mouse that was used for the click.  This is the same as the MOUSEBUTTONUP event&#8217;s button attribute.</li>
<li>pos (x,y) &#8211; The position of the mouse cursor when the click occurred.  The is the same as the MOUSEBUTTONUP event&#8217;s pos attribute.</li>
<li>text_widget &#8211; The TextWidget object that was clicked on, so you know how to handle the event.</li>
</ul>
<p>That is the default way that the on_mouse_click() function functions, in general it is probably easier to override the on_mouse_click() function in all of the TextWidget instances that you want to be interactive.</p>
<p>As an example, in your main application you might use the following for an Exit TextWidget:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked</span></pre></div></div>
<h2>Using the TextWidget</h2>
<p>In order to make it easy to see how to use the TextWidget object (if it is not already) I whipped up a quick sample application, the short flash capture is to show you what it looks like without having to run it:</p>
<p>
<embed src="http://www.learningpython.com/flash/textwidget.swf" width="320" height="240" play="true" loop="True" quality="low" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"><br />
</embed>
</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">os</span><span class="hl-default">, </span><span class="hl-identifier">sys
</span><span class="hl-reserved">import </span><span class="hl-identifier">pygame
</span><span class="hl-reserved">from </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals </span><span class="hl-reserved">import</span><span class="hl-default"> *

</span><span class="hl-reserved">import </span><span class="hl-identifier">TextWidget

</span><span class="hl-reserved">class </span><span class="hl-identifier">PyGameText</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">An example class used to illustrate possible ways to work
    with the TextWidget text in a pygame game.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">width</span><span class="hl-code">=</span><span class="hl-number">640</span><span class="hl-code">, </span><span class="hl-identifier">height</span><span class="hl-code">=</span><span class="hl-number">480</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize
        @param width=640 - The width of the pygame window
        @param height=480 - The height of the pygame window.
        </span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">init</span><span class="hl-brackets">()
        </span><span class="hl-comment">#create the screen
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">set_mode</span><span class="hl-brackets">((</span><span class="hl-identifier">width</span><span class="hl-code">, </span><span class="hl-identifier">height</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-brackets">) 
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">Surface</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-code">.</span><span class="hl-identifier">get_size</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-identifier">SWSURFACE</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">convert</span><span class="hl-brackets">()
        </span><span class="hl-identifier">image</span><span class="hl-default">, </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">load_image</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">background.png</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">image</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">image</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-comment">#Just fill with a solid colour
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">fill</span><span class="hl-brackets">((</span><span class="hl-number">124</span><span class="hl-code">,</span><span class="hl-number">124</span><span class="hl-code">,</span><span class="hl-number">124</span><span class="hl-brackets">))
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">background</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
        
    </span><span class="hl-reserved">def </span><span class="hl-identifier">main_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">The main Python loop</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">time</span><span class="hl-default">.</span><span class="hl-identifier">Clock</span><span class="hl-brackets">()
        
        </span><span class="hl-comment"># Text Widget list
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default"> = </span><span class="hl-brackets">[]
        </span><span class="hl-comment">#Create our Text WIdgets
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">New Game</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-brackets">))
        </span><span class="hl-comment">#make this the biggest text
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-number">96
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-number">0</span><span class="hl-default">;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">new_game_text</span><span class="hl-brackets">)
        
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">High Scores</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">high_score_text</span><span class="hl-brackets">)
        
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Website</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">website_text</span><span class="hl-brackets">)
        
        </span><span class="hl-comment"># Different font for the last one, and let's make it increase
        # more
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Exit</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">
                                , </span><span class="hl-number">64</span><span class="hl-code">, </span><span class="hl-number">40</span><span class="hl-code">
                                , </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-code">.</span><span class="hl-identifier">match_font</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sans</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-reserved">False</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">))
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked
        self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">exit_text</span><span class="hl-brackets">)
           
        </span><span class="hl-reserved">while </span><span class="hl-number">1</span><span class="hl-default">: 
            </span><span class="hl-comment">#Tick of the timer
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default">.</span><span class="hl-identifier">tick</span><span class="hl-brackets">()
            
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">event_loop</span><span class="hl-brackets">()
            
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
                
    </span><span class="hl-reserved">def </span><span class="hl-identifier">event_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Perform the event loop.</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-reserved">for </span><span class="hl-identifier">event </span><span class="hl-reserved">in </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">get</span><span class="hl-brackets">()</span><span class="hl-default">:
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">QUIT</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
                </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">ACTIVEEVENT</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">gain</span><span class="hl-code"> == </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-default">:
                    </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                        </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
                    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
                </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">state</span><span class="hl-code"> ==</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-default">: 
                    </span><span class="hl-comment">#We are hidden so wait for the next event
                    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">wait</span><span class="hl-brackets">())             
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEMOTION</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONDOWN</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONUP</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget             
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw everything</span><span class="hl-quotes">&quot;&quot;&quot;        
        </span><span class="hl-identifier">rects</span><span class="hl-default"> = </span><span class="hl-brackets">[]
        </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">timer_update</span><span class="hl-brackets">())
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-brackets">)
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">(</span><span class="hl-identifier">rects</span><span class="hl-brackets">)        
        
    </span><span class="hl-reserved">def </span><span class="hl-identifier">timer_update</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Update the Timer
        returns - pygame.rect - The rect that the timer
        needs to be redrawn, or None on error</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-reserved">None
        
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-brackets">)</span><span class="hl-default">:     
            </span><span class="hl-identifier">timer_string</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">%.2f</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default">.</span><span class="hl-identifier">get_fps</span><span class="hl-brackets">()
            </span><span class="hl-comment">#basic font
            </span><span class="hl-identifier">font</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">Font</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-number">36</span><span class="hl-brackets">)
            </span><span class="hl-identifier">message</span><span class="hl-default"> = </span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">render</span><span class="hl-brackets">(</span><span class="hl-identifier">timer_string</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">147</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-code">, </span><span class="hl-number">16</span><span class="hl-brackets">))
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">message</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">message</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">(</span><span class="hl-identifier">left</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-brackets">)
                </span><span class="hl-identifier">rect_return</span><span class="hl-default">.</span><span class="hl-identifier">width</span><span class="hl-default"> += </span><span class="hl-number">25
                </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">background</span><span class="hl-code">, </span><span class="hl-identifier">rect_return</span><span class="hl-brackets">)
                </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">message</span><span class="hl-code">, </span><span class="hl-identifier">rect_return</span><span class="hl-brackets">) 
        
        </span><span class="hl-reserved">return </span><span class="hl-identifier">rect_return
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">load_image</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">name</span><span class="hl-code">, </span><span class="hl-identifier">colorkey</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">full_path</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">realpath</span><span class="hl-brackets">(</span><span class="hl-identifier">os</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-code">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]))
        </span><span class="hl-identifier">full_path</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">full_path</span><span class="hl-code">, </span><span class="hl-identifier">name</span><span class="hl-brackets">)
        </span><span class="hl-reserved">try</span><span class="hl-default">:
            </span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">load</span><span class="hl-brackets">(</span><span class="hl-identifier">full_path</span><span class="hl-brackets">)
        </span><span class="hl-reserved">except </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">error</span><span class="hl-default">, </span><span class="hl-identifier">message</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">'</span><span class="hl-string">Cannot load image:</span><span class="hl-quotes">'</span><span class="hl-default">, </span><span class="hl-identifier">full_path
            </span><span class="hl-reserved">return None</span><span class="hl-default">, </span><span class="hl-reserved">None
        </span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">convert</span><span class="hl-brackets">()
        </span><span class="hl-reserved">if </span><span class="hl-identifier">colorkey </span><span class="hl-reserved">is not None</span><span class="hl-default">:
            </span><span class="hl-reserved">if </span><span class="hl-identifier">colorkey </span><span class="hl-reserved">is</span><span class="hl-default"> -</span><span class="hl-number">1</span><span class="hl-default">:
                </span><span class="hl-identifier">colorkey</span><span class="hl-default"> = </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_at</span><span class="hl-brackets">((</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
            </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">set_colorkey</span><span class="hl-brackets">(</span><span class="hl-identifier">colorkey</span><span class="hl-code">, </span><span class="hl-identifier">RLEACCEL</span><span class="hl-brackets">)
        </span><span class="hl-reserved">return </span><span class="hl-identifier">image</span><span class="hl-default">, </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">on_exit_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
        </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">PyGameText</span><span class="hl-brackets">()
    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">main_loop</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now most of the code isn&#8217;t that exciting and is a pretty basic example of a short PyGame application so I won&#8217;t explain every line of this code.  I will highlight three portions:</p>
<h3>Text Widget Creation</h3>
<p>Here is how I created the four TextWidgets in the example application, each is slightly different so you might want to look at each and try to understand what it is doing:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># Text Widget list
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default"> = </span><span class="hl-brackets">[]
</span><span class="hl-comment">#Create our Text WIdgets
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">New Game</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-brackets">))
</span><span class="hl-comment">#make this the biggest text
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-number">96
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-number">0</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">new_game_text</span><span class="hl-brackets">)

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">High Scores</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">high_score_text</span><span class="hl-brackets">)

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Website</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">website_text</span><span class="hl-brackets">)

</span><span class="hl-comment"># Different font for the last one, and let's make it increase
# more
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Exit</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">
                        , </span><span class="hl-number">64</span><span class="hl-code">, </span><span class="hl-number">40</span><span class="hl-code">
                        , </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-code">.</span><span class="hl-identifier">match_font</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sans</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-reserved">False</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">))
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-comment"># Override the on_mouse_click function
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked
self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">exit_text</span><span class="hl-brackets">)</span></pre></div></div>
<p>In general this code is pretty simple, it mostly involves creating our TextWidget objects, settings some of their properties and then adding them to a list.  It really should be pretty self explanatory how this code works, one thing that I will point out is how the in the exit_text TextWidget the pygame.font.match_font() function is used to get the path to the font, and the on_mouse_click() function is overridden.</p>
<h3>The Event Loop</h3>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">event_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Perform the event loop.</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">for </span><span class="hl-identifier">event </span><span class="hl-reserved">in </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">get</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">QUIT</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
        </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">ACTIVEEVENT</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">gain</span><span class="hl-code"> == </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
        </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">state</span><span class="hl-code"> ==</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-default">: 
            </span><span class="hl-comment">#We are hidden so wait for the next event
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">wait</span><span class="hl-brackets">())             
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEMOTION</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONDOWN</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONUP</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget</span></pre></div></div>
<p>The first thing you should notice is that we respond to the ACTIVEEVENT, we do this so that when the PyGame window gets focus back (after loosing it) we redraw all of the text widgets.  We force the TextWidgets to redraw by setting the dirty member to True.</p>
<p>Next we set the TextWidget.highlight property by checking for a collision with each TextWidget rect when we get the MOUSEMOTION event.</p>
<p>If you want your TextWidgets to be responsive to a click whenever you get a MOUSEBUTTONDOWN or MOUSEBUTTONUP event you can simply pass it forward to the on_mouse_button_down() and on_mouse_button_up() functions in each widget, the TextWidget will take care of the rest of the processing.</p>
<p>The example also shows how to handle the TEXT_WIDGIT_CLICK event:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget</span></pre></div></div>
<p>In the example I simply print out the TextWidget, but you could do whatever you wanted to.</p>
<h3>The Draw Loop</h3>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw everything</span><span class="hl-quotes">&quot;&quot;&quot;        
    </span><span class="hl-identifier">rects</span><span class="hl-default"> = </span><span class="hl-brackets">[]
    </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">timer_update</span><span class="hl-brackets">())
    </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
        </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-brackets">)
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">(</span><span class="hl-identifier">rects</span><span class="hl-brackets">)</span></pre></div></div>
<p>The draw loop is actually pretty simple.  I use a list to keep track of rectangles that I want to update at the end of the draw using <a href="http://www.pygame.org/docs/ref/display.html#pygame.display.update">pygame.display.update()</a> function.</p>
<p>In order to draw the TextWidget&#8217;s I simply loop through the list of them and call their draw() function.  If the draw() function returns a rectangle, then I know that the TextWdiget has drawn so I add it to the list of rectangles that need to be updated.  </p>
<p>If None is returned then I know that the TextWidget has not drawn and that it does not need to be drawn. </p>
<h2>Conclusion</h2>
<p>The full source and necessary files for this tutorial can be downloaded <a href="http://www.learningpython.com/sources/TextWidget.tar.gz">here</a>.</p>
<p>So that&#8217;s it for this tutorial, as I said early on I&#8217;m not saying that this is the best or only way to work with text, I&#8217;m simply presenting this as a possible way to work with text, or as an example that might help get you started with your own text processing.</p>
<p>If you have any suggestions, problems, or notice anything that is incorrect, as always, add a comment! </p>
<p>Feel free to use this in whatever manner you want (it&#8217;s licensed under the LGPL), but if you do end up using it, I would appreciate it if you sent me an email and let me know.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/&title=TextWidget - A simple text class for PyGame&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
