<?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>Canvas &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/canvas/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 08 Sep 2025 17:57:41 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Year of Code 2025: September Project, Games</title>
		<link>https://blog.xojo.com/2025/09/08/year-of-code-2025-september-project-games/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 08 Sep 2025 17:57:38 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[#YearofCode]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[GitLab]]></category>
		<category><![CDATA[Year of Code]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15311</guid>

					<description><![CDATA[I&#8217;m a bit of a retro computing and gaming guy and I enjoy making versions of retro games using Xojo. Although Xojo is not really&#8230;]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;m a bit of a <a href="https://www.goto10retro.com">retro computing and gaming guy</a> and I enjoy making versions of retro games using Xojo. Although Xojo is not really designed for making games, its <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopcanvas.html#desktopcanvas">Canvas</a> class works well for many kinds of simple games. That means our theme for the Year of Code for September is Games!</p>



<p>One of the first games I made using Xojo was a clone of Atari Tank (based on the version included with the Combat Atari 2600 cartridge).</p>



<p>The core of Tank served as the basis for the <a href="https://github.com/xojo/XojoWars">XojoWars game contest</a>, where it was re-imagined as a space battle.</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="400" height="308" src="https://blog.xojo.com/wp-content/uploads/2025/08/image-1.png" alt="" class="wp-image-15314" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/image-1.png 400w, https://blog.xojo.com/wp-content/uploads/2025/08/image-1-300x231.png 300w" sizes="(max-width: 400px) 100vw, 400px" /></figure>



<p>Tank is a rather simple game and really needs to be two-players, which is why I added the ability for two people to play it over the network using UDPSocket. This version, which I called <a href="https://blog.xojo.com/2018/08/24/justcode-challenge-week-10-nettank/">NetTank</a>, is <a href="https://gitlab.com/xojo/NetTank">available on GitLab</a>.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="367" src="https://blog.xojo.com/wp-content/uploads/2025/08/image-1024x367.png" alt="" class="wp-image-15313" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/image-1024x367.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/image-300x107.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/image-768x275.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/image.png 1220w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>On the mobile side, I&#8217;ve made a 2048 sliding-tiles game and Turtle, which I suppose is kind of an infinite version of Frogger.</p>



<p>However, I&#8217;ve had the most fun making clones of Asteroids and Space Invaders. I wrote some about Invaders in <a href="https://www.xdevmag.com">xDev Magazine</a> last year, but at some point I&#8217;ll get it enhanced enough to share in a blog post.</p>



<p>With that lengthy pre-amble I can now share my game for this month&#8217;s project, which is a clone of Asteroids that I uncreatively call Space Rocks. Although an older version of this game has been included with the Xojo examples for several years, this is an updated version with some new features:</p>



<ul class="wp-block-list">
<li>Smaller ship to better match proportions of the rocks.</li>



<li>Improved &#8216;heartbeat&#8217; sound.</li>



<li>High Score is saved and restored.</li>



<li>Level increases as you clear all the rocks, which adds even more rocks that also move faster.</li>



<li>Command or Shift key now work for firing missiles.</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="850" src="https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x-1024x850.png" alt="" class="wp-image-15316" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x-1024x850.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x-300x249.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x-768x637.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x-1536x1275.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.21.38@2x.png 2024w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="850" src="https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x-1024x850.png" alt="" class="wp-image-15315" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x-1024x850.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x-300x249.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x-768x637.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x-1536x1275.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/CleanShot-2025-08-25-at-14.23.20@2x.png 2024w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Yes, 14340 is my high score. So far. I dare you to beat it!</p>



<p>The full project is on GitHub: <a href="https://github.com/paullefebvre/SpaceRocks">https://github.com/paullefebvre/SpaceRocks</a></p>



<p>Keep in mind that you don&#8217;t have to make an arcade-style game. Strategy and turn-based games are a lot of fun and also  great candidates for Xojo. For reference, take a look at the <a href="https://blog.xojo.com/2024/09/17/cosmic-trader-a-game-built-with-xojo-web/">web-based Cosmic Trader game</a> that Ricardo made last year. A platform-style or maze game might also be interesting. I can&#8217;t wait to see (and play) what you make!</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Year of Code Project</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/01/09/year-of-code-2025-kickoff/">Year of Code: Kickoff</a></li>



<li><a href="https://blog.xojo.com/2025/01/15/year-of-code-2025-january-project/" target="_blank" rel="noreferrer noopener">January Project: Desktop Apps</a>&nbsp;|&nbsp;<a href="https://forum.xojo.com/t/year-of-code-2025-january-project-sharing/83927" target="_blank" rel="noreferrer noopener">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/02/11/year-of-code-2025-february-project/">February Project: Database Apps</a>&nbsp;|&nbsp;<a href="https://forum.xojo.com/t/2025-year-of-code-february" target="_blank" rel="noreferrer noopener">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/03/05/year-of-code-2025-march-project-web-apps/">March Project: Web Apps</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-march/84474?u=alyssa_foley">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/04/08/year-of-code-2025-april-project-user-interface/">April Project: User Interface</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-april-user-interface/84926">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/05/07/year-of-code-2025-may-project-mobile-apps/">May Project: Mobile Apps</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-may-is-mobile/85272">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/06/10/year-of-code-2025-june-project-cross-platform-code-class/">June Project: Code Sharing</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-june-is-code-sharing/85612">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/07/10/year-of-code-2025-july-project-charting/">July Project: Charting</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-july-is-charting/85896">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/08/07/year-of-code-2025-august-project-console-apps/">August Project: Console Apps</a> | <a href="https://forum.xojo.com/t/august-2025-year-of-code-console-apps/86203">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/09/08/year-of-code-2025-september-project-games/">September Project: Games</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-septgamer">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/10/13/year-of-code-2025-october-project-multi-platform-communication/">October Project: Multi-Platform</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-october-multi-platform-communication/86717">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/11/10/year-of-code-2025-november-project-pdf-postcard-generator/">November Project: PDF</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-november-pdf/86969">Forum Discussion</a></li>
</ul>



<p><strong>How to Play:</strong></p>



<p>Each month we&#8217;ll announce a new theme and share an example project of our own. Share your projects to the Xojo Forum thread for that month via GitHub (all the links you need are posted above ↑ ). Learn how to use <a href="https://blog.xojo.com/2024/04/02/using-xojo-and-github/">Xojo and GitHub</a>.</p>



<p><strong>The Prizes:</strong></p>



<p>Monthly winners get $100 at the Xojo store. Every month you submit a project is another chance to win the grand prize. The grand prize is $250 cash plus a Xojo Pro license and a year of GraffitiSuite and will be announce in December. Learn more about the <a href="https://blog.xojo.com/2025/01/09/year-of-code-2025-kickoff/#prizes">prizes</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>iOS: KeyDown Arrives to MobileCanvas</title>
		<link>https://blog.xojo.com/2023/08/09/ios-keydown-arrives-to-mobilecanvas/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 09 Aug 2023 13:30:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[iOSCanvas]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[MobileCanvas]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11744</guid>

					<description><![CDATA[As a direct result of user feedback, starting with Xojo 2023r2, the MobileCanvas control on iOS can now receive KeyDown events from the user, both from the on-device keyboard and any connected keyboard. In addition, this support is available in MobileTextArea, MobileTextField and MobileScreen.]]></description>
										<content:encoded><![CDATA[
<p>As a direct result of user feedback, starting with Xojo 2023r2, the MobileCanvas control on iOS can now receive KeyDown events from the user, both from the on-device keyboard and any connected keyboard. In addition, this support is available in MobileTextArea, MobileTextField and MobileScreen.</p>



<span id="more-11744"></span>



<p>In order for the MobileCanvas to receive <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilecanvas.html#mobilecanvas-keydown">KeyDown</a> events, the control instance needs to be Enabled and have its focus set. In addition, the new <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilecanvas.html#mobilecanvas-allowkeyevents">AllowKeyEvents</a> property needs to be set to True.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="473" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-473x1024.png" alt="" class="wp-image-11745" srcset="https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-473x1024.png 473w, https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-139x300.png 139w, https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-768x1662.png 768w, https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-710x1536.png 710w, https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas-946x2048.png 946w, https://blog.xojo.com/wp-content/uploads/2023/07/KeyDownOnCanvas.png 1170w" sizes="auto, (max-width: 473px) 100vw, 473px" /></figure>
</div>


<p>If the Canvas receives the KeyDown event, the on-device keyboard will be hidden as soon its focus is cleared or the control Enabled property is set to False.</p>



<p>In addition to the new KeyDown event, there is also a new TextReceived event that, if implemented in the instance, will be fired when the control receives, for example, text from the Dictation feature when the text is more than just one character in length.</p>



<p>Lastly, while <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilecanvas.html#mobilecanvas">MobileCanvas</a>, <a href="https://documentation.xojo.com/api/user_interface/mobile/mobiletextfield.html#mobiletextfield">MobileTextField</a> and <a href="https://documentation.xojo.com/api/user_interface/mobile/mobiletextarea.html#mobiletextarea">MobileTextArea</a> can only receive KeyDown events, the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilescreen.html#mobilescreen">MobileScreen</a> object can also receive KeyUp events. See this in action in this short video: <a href="https://youtu.be/LNMMSTNoG8Y">KeyDown events on MobileCanvas on iOS</a>.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Back to School: Graphing Simple Functions</title>
		<link>https://blog.xojo.com/2022/08/31/back-to-school-graphing-simple-functions/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 31 Aug 2022 17:45:18 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Graphing]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10689</guid>

					<description><![CDATA[I was recently asked if there was a way to use Xojo Canvas Graphics to draw using the math X-Y coordinate system. First a little background. In Xojo (along with Java, .NET and many other languages), graphics are drawn where (0,0) is at the top left, X increases to the right and Y increases down. Other languages or APIs (Cocoa, for example) use a system where (0,0) is at the bottom left, X increases to the right and Y increases up.]]></description>
										<content:encoded><![CDATA[
<p>I was recently asked if there was a way to use Xojo Canvas Graphics to draw using the math X-Y coordinate system. First a little background. In Xojo (along with Java, .NET and many other languages), graphics are drawn where (0,0) is at the top left, <em>X</em> increases to the right and <em>Y</em> increases down. Other languages or APIs (Cocoa, for example) use a system where (0,0) is at the bottom left, <em>X</em> increases to the right and <em>Y</em> increases up.</p>



<p>In mathematics, (0,0) is typically at the center with positive <em>X</em> being to right, negative <em>X</em> to the left. Positive Y is up and negative <em>Y</em> is down.</p>



<p>This means if you are trying to draw the graphs of some standard math functions you have to do some translating. With Xojo you can use the <a href="https://documentation.xojo.com/api/graphics/graphics.html#graphics-translate">Graphics.Translate()</a> function to relocate the origin point. This makes it easy to move (0,0) from the top left to the center with code like this in the Paint event:</p>



<pre class="wp-block-preformatted"><code>g.Translate(g.Width / 2, g.Height / 2)</code></pre>



<p>Switching the <em>Y</em> from going from the top down to the bottom up is just a matter of negating it. With a translated origin, this would draw a line above the baseline:</p>



<pre class="wp-block-preformatted"><code>g.DrawLine(1, -2, 1, -2)</code></pre>



<p>I thought it might be interesting to try and wrap this up in some subclasses to make it a little more automatic, work with the smaller scale typically used for these type of graphs and even graph some functions.</p>



<p>The result is a project, MathGraph, which can draw some shapes on the graph and also graph simple functions that work with <em>x</em>.</p>



<p>Here&#8217;s an example of a graph for the cubic polynomial function y = x^3:</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-14.10.56@2x-1024x777.png" alt="" class="wp-image-10691" width="635" height="482" srcset="https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-14.10.56@2x-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-14.10.56@2x-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-14.10.56@2x-768x582.png 768w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-14.10.56@2x.png 1424w" sizes="auto, (max-width: 635px) 100vw, 635px" /></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Keep in mind that this only solves for <em>x</em>.</p></blockquote>



<p>Other functions you might want to try:</p>



<ul class="wp-block-list"><li>quadratic polynomial: x^2</li><li>line: x</li><li>absolute value: abs(x)</li><li>reciprocal of x: 1/x</li><li>reciprocal of&nbsp;<em>x</em><sup>2</sup>: 1/x^2</li><li>square root: sqrt(x)</li><li>exponential: exp(x)</li><li>logarithmic: log(x)</li><li>sin wave: sin(x)</li><li>sin(x)/cos(x)</li></ul>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-16.10.16@2x-1024x777.png" alt="" class="wp-image-10694" width="648" height="492" srcset="https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-16.10.16@2x-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-16.10.16@2x-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-16.10.16@2x-768x582.png 768w, https://blog.xojo.com/wp-content/uploads/2022/08/CleanShot-2022-08-23-at-16.10.16@2x.png 1424w" sizes="auto, (max-width: 648px) 100vw, 648px" /></figure>



<p>Try multiplying and dividing some of the above in combination. You can use any valid Xojo math expression and any of the <a href="https://documentation.xojo.com/topics/xojoscript/xojoscript_functions.html#topics-xojoscript-xojoscript-functions-math">math functions</a>. If there is an error in your function, then the error message is shown in the graph itself.</p>



<p>There are also some built in functions to draw text, rectangles, ovals and plot points that you can use in the Paint event handler.</p>



<p>This is provided as a Canvas subclass, called MathCanvas. It has companion classes MathGraphics and Grapher. MathGraphics is used to draw using math coordinates. Grapher is a subclass of <a href="https://documentation.xojo.com/api/code_execution/xojoscript.html">XojoScript</a> and is what processes the function for graphing (it is based on the Evaluator example project included with Xojo).</p>



<p><a href="https://files.xojo.com/BlogExamples/MathGraph.xojo_binary_project">Download the MathGraph</a> project to try it for yourself. </p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Cross-Platform Mobile Bounce Animation</title>
		<link>https://blog.xojo.com/2021/03/17/cross-platform-mobile-bounce-animation/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 17 Mar 2021 18:04:06 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[iOSCanvas]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8175</guid>

					<description><![CDATA[Here's a fun little project you can try to get a feel for some simple animation in your iOS and future Android apps.]]></description>
										<content:encoded><![CDATA[
<p>Here&#8217;s a fun little project you can try to get a feel for simple animation in your iOS apps. As you can see, this project moves a small &#8220;ball&#8221; around the screen and it bounces off the edges.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="448" height="799" src="https://blog.xojo.com/wp-content/uploads/2021/03/CleanShot-2021-03-11-at-17.25.02.gif" alt="" class="wp-image-8177"/></figure>



<p>Create a new iOS project and on Screen1 add a couple Buttons and a Canvas, the buttons at the top and the Canvas using up the rest of the space. Also add a Timer.</p>



<p>Add some properties to track the ball&#8217;s position and direction:</p>



<ul class="wp-block-list"><li>Public Property XDirection as Integer = 10</li><li>Public Property XPosition as Integer = 10</li><li>Public Property YDirection as Integer = 10</li><li>Public Property YPosition as Integer = 10</li></ul>



<p>In the Opening event for Screen1, initialize the Timer (which I&#8217;ve named MoveTimer):</p>



<pre class="wp-block-preformatted">MoveTimer.Period = 50
MoveTimer.RunMode = Timer.RunModes.Multiple
MoveTimer.Enabled = False</pre>



<p>Speaking of the Timer, in its Run event put this code to move the ball:</p>



<pre class="wp-block-preformatted">XPosition = XPosition + XDirection
YPosition = YPosition + YDirection
BounceCanvas.Refresh</pre>



<p>Add the Paint and PointerDown events to the Canvas. In the Paint event draw the ball with this code:</p>



<pre class="wp-block-preformatted">Var size As Integer = 25
g.DrawingColor = Color.RGB(255, 0, 0)
g.DrawRectangle(0, 0, g.Width, g.Height)
g.FillOval(XPosition, YPosition, size, size)
If (XPosition + size) &gt; g.Width Then
  XDirection = -XDirection
End If
If ( YPosition + size) &gt; g.Height Then
  YDirection = -YDirection
End If
If XPosition &lt; 0 Then
  XDirection = -XDirection
End If
If YPosition &lt; 0 Then
  YDirection = -YDirection
End If</pre>



<p>And in the PointerDown event, reset the ball&#8217;s position to the touch:</p>



<pre class="wp-block-preformatted">XPosition = position.X
YPosition = position.Y
XDirection = -XDirection
YDirection = -YDirection</pre>



<p>Lastly you can add the Pressed event to the Start button and tell it to start the Timer:</p>



<pre class="wp-block-preformatted">MoveTimer.Enabled = True</pre>



<p>Similarly add the Pressed event to the Stop button and tell it to stop the Timer:</p>



<pre class="wp-block-preformatted">MoveTimer.Enabled = False</pre>



<p>That&#8217;s it. Run the project, click start to watch the ball bounce. Tap on the screen to change its position and direction. You could probably use this as the start of a Pong game!</p>



<p>Oh, and I forgot to mention that the code above was actually copied from the Android project where I first created this. The exact code copied over to iOS and worked as is with no changes. For a little teaser, here&#8217;s Bounce running on Android:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="377" height="799" src="https://blog.xojo.com/wp-content/uploads/2021/03/CleanShot-2021-03-11-at-17.19.43.gif" alt="" class="wp-image-8176"/></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Detecting Right Mouse Button Presses</title>
		<link>https://blog.xojo.com/2020/01/09/detecting-right-mouse-button-presses/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 09 Jan 2020 15:43:48 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6408</guid>

					<description><![CDATA[In a desktop Canvas control you have two ways to handle a right mouse button press.]]></description>
										<content:encoded><![CDATA[
<p>In a desktop <a href="https://documentation.xojo.com/api/deprecated/canvas.html">Canvas</a> control you have two ways to handle a right mouse button press.</p>



<p>The most common situation is that you want to show a menu when the right mouse button is pressed. You can do this using the <a href="https://documentation.xojo.com/api/deprecated/rectcontrol.html#rectcontrol-constructcontextualmenu">ConstructContextualMenu</a> and <a href="https://documentation.xojo.com/api/deprecated/rectcontrol.html#rectcontrol-contextualmenuaction">ContextualMenuAction</a> events.</p>



<p>For example, say you have a Canvas on a Window and want to display a menu when the user right-clicks in it. Add the CreateContextualMenu event to create your menu like this:</p>



<pre class="wp-block-preformatted">base.AddMenu( New MenuItem("Test 1"))<br>base.AddMenu( New MenuItem("Test 2"))<br>base.AddMenu( New MenuItem("Test 3"))</pre>



<p>Then add the ContextualMenuAction event to check which menu was selected (provided by the hitItem parameter) and perform a corresponding action:</p>



<pre class="wp-block-preformatted">If hitItem &lt;&gt; Nil Then MessageBox(hitItem.Value)
Return True</pre>



<p>Alternatively you may want to just know if the right mouse button was pressed so that it can perform another action rather than displaying a menu. For example, in the case of a Canvas maybe it changes a drawing color or marks a location. In situations like this you can also check for a right mouse button press in the <a href="https://documentation.xojo.com/MouseDown_event">MouseDown</a> event handler by using the <a href="https://documentation.xojo.com/api/language/is.htmlContextualClick">IsContextualClick</a> method like this:</p>



<pre class="wp-block-preformatted">If IsContextualClick Then
  MessageBox("Right mouse button clicked.")
Else
  MessageBox("Left mouse button clicked.")
End If</pre>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Canvas: How to Create Custom UI Controls</title>
		<link>https://blog.xojo.com/2019/04/15/canvas-how-to-create-custom-ui-controls/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 15 Apr 2019 10:00:47 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[AprendeXojo]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[iOSCanvas]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[WebCanvas]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5649</guid>

					<description><![CDATA[Sometimes, subclassing the available controls is the answer to add specific behaviors you need. But what happen when none of the controls offer what you need, whether visually or functionally? The answer is the Canvas class (for Desktop projects), WebCanvas class (for Web projects) and iOSCanvas class for iPhone and iPad devices. ]]></description>
										<content:encoded><![CDATA[<p>Xojo includes a good amount of <b>UI</b> controls available from the Library for <strong>Desktop</strong>, <strong>Web</strong>, <strong>iOS</strong> and <strong>Raspberry Pi</strong> targets. These are the pieces that allow you to layout the user interface of your apps: properties, methods and events that, when combined, define the specific behavior of the project at hand.</p>
<p>Sometimes, subclassing the available controls is the answer to add specific behaviors you need. But what happen when none of the controls offer what you need, whether visually or functionally? The answer is the Canvas class (for Desktop projects), WebCanvas class (for Web projects) and iOSCanvas class for iPhone and iPad devices. But how do you create your own UI controls from scratch? Read on to learn&#8230;<span id="more-5649"></span></p>
<p>Before starting with this basic tutorial about customized UI controls, there is much more to take into consideration about providing the same behavior on your designed controls for multiplatform deployments. For example, in the case of desktop projects, we should add to the mix some things like <strong>HiDPI</strong> / <strong>Retina</strong> detection and adaptation on the fly (specially in the case of Windows deployment, with multiple dpi / Windows OS version combinations), and <strong>Dark Mode</strong> support for macOS. A well as other performance hints and differences when it&#8217;s about doing desktop multiplatform layouts; for example, when to set the <code>Transparent</code> or <code>DoubleBuffer</code> properties to <code>True</code> or not.</p>
<p>As the name implies, the Canvas control acts like a painting canvas and you can set its look for all the supported states based on the available events. This is done through the <code>Paint</code> Event and all the <a href="http://documentation.xojo.com/api/graphics/graphics.html"><b>Graphic</b></a> classes availables in the Framework. In fact, the <b>Paint</b> event provides as a parameter the graphical context (canvas height and width) you can paint on. In addition, you can combine these graphic classes (or completely substitute them) with any prepared <b>Picture</b> of your choice as the customize control background (<a href="http://documentation.xojo.com/getting_started/using_the_ide/image_set_editor.html"><b>ImageSet</b></a> recommended, so it supports all the needed resolutions based on display dpi). In addition, and as you can do with the drawing via the Graphic class and functions, you can choose to use a different <a href="http://documentation.xojo.com/api/graphics/picture.html"><b>Picture</b></a> as the control background based on several events, for example, when the mouse pointer is entering or exiting the control limits in a Desktop or Web app, or as response to the user clicking on it.</p>
<h2>Canvas: A matter of Events</h2>
<p>The <a href="http://documentation.xojo.com/api/deprecated/canvas.html">Canvas class</a> provides all the needed Events you probably would want to implement in order to react to the user interaction. These are listed and described in the available documentation online and as part of the Xojo IDE interactive Help.</p>
<p>While you can drag and drop a Canvas instance directly to your project layout window or view, implementing and writing the code associated with  any of the available Events, the recommended way to go is to create your own subclass taking as its parent the Canvas class. This way, you can implement and fine-tune every aspect that makes you control unique and, most importantly, re-use your customized UI controls as many times you want both in current and future projects (or even <a href="https://documentation.xojo.com/Resources:Free_Source_Code_and_Tools">offer them</a> to the Xojo community or <a href="https://www.xojo.com/store/#addons">sell them</a> to other developers!).</p>
<p>As you probably already know, in an <b>OOP programming language</b>, subclassing is the method to get a specialized behavior from an existing Class: We get for free all the available properties, methods and events from the parent (and all its parent hierarchy), including also the code executed in the Paint event to truly paint or provide its look on screen; so we just need to implement the specific behavior and/or control drawing/painting we need over these.</p>
<p>This is also the way to go when you are in the inital stages of designing your own customized UI control: will you need to create even more specialized behaviors based on a &#8220;parent&#8221; or base customized control? Maybe variations on the behavior? In cases like these, you should define your UI control base class at the bare-minimum set of painting, behavior (events and methods) and properties that will be shared from all the future UI Controls inherited from your base/parent UI Control class. (i.e: more specialized or with behavior variations).</p>
<p>Creating a subclass in Xojo is truly simple: just drag and drop the Canvas icon from the <b>Library</b> to the <b>Navigator</b> (the leftmost column in the Xojo IDE), or choose <code>Insert &gt; Class</code> from the Insert menu.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-5650 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/04/Canvas-Library.png" alt="" width="260" height="317" /></p>
<h2>Points vs Pixels: HiDPI and Retina</h2>
<p>Once you have added the new Class to your project, select it, go to the Inspector and set the name you want to use for your new Class (using a &#8220;company&#8221; or personal prefix it&#8217;s always a good idea to avoid collision with other existing or future classes in the Xojo Framework, or when using third party classes). Then, in the <b>Super</b> field of the Inspector Panel, type <code>Canvas</code> and confirm the entry. You&#8217;ll see how your class icon changes to the one that uniquely identifies Canvas based classes and instances. The most important thing: your new subclass will have all the properties, events and methods you may expect from a Canvas.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-5651 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/04/Subclase-Canvas.png" alt="" width="261" height="234" /></p>
<p>This will be the base class in our short tutorial for creating a customized button that will change its associated image (picture) when the mouse pointer is inside the button area, outside the button bounds or when the user click on the control. In the last case, the button will change both the image and its internal state represented by a property as a Boolean value (named <code>Status</code>).</p>
<p>As our customized UI control will not draw itself via the Paint event, we will need to design the images so these precisely fit in the size we want to use for our button. In this example a size of 32 x 32 points.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-5652 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/04/Sketch-Graficos-1024x650.png" alt="" width="1024" height="650" /></p>
<p>In general, when designing images to use in our Xojo projects we need to change our mindset from thinking in pixels to points. That&#8217;s because Xojo apps do support <b>HiDPI</b> on Windows/Linux and <b>Retina</b> on macOS; that is: hi-def graphics. Thus, it&#8217;s important to use a design tool that simplifies the process. Personally, I use the vectorial app Sktech on macOS because it automates the 2x creation of the final images. (Remember that HiDPI/Retina is enabled by default in the Building Settings on every new Desktop project.)</p>
<p>How do you support HiDPI/Retina if you want to draw the control look on the fly? Avoid the use of pixels in your calculations or when setting the values of the existing Graphic class properties, and use Points instead. If you really need to access the Pixels values underneath, then you can resort to the <code>RGBSurface</code> class (if available) and make use of the <code>ScaleFactorChanged</code> event available on the Canvas class. This way, your class will be notified on every change between displays with or withour Retina/HiDPI support.</p>
<p>Good rule of thumb: do all your control drawing inside the Paint event! And, when you need to update or redraw it (maybe as consequence of some change in the app behavior, or from the change made in other UI control), invoke the method <code>Invalidate</code> instead of <code>Refresh</code>. In general, this will speed up the drawing and, thus, the main app performance.</p>
<h2>If you use an existing Event… Define the Event again</h2>
<p>As our customized class makes use of the <b>Open</b>, <b>MouseEnter</b>, <b>MouseExit</b> and <b>MouseDown</b> Events, we need to make sure we define these events again to the class, so they are also available for the developer using our canvas-based UI subclass. After all, it&#8217;s very probable he needs or wants to add extra code on top of ours! This is something we can do choosing <code>Add to "class_name" &gt; Event definition</code> when our subclass icon is selected in the Navigation Browser.</p>
<p>Thus, once we have created the same events (using the same parameters and returning the same kind of Type values as the original ones), we need to make sure we call them; usually as the last line of code for the already used Event. For example, this is the code for our implementation of the <code>MouseDown</code> event in our Canvas subclass:</p>
<pre>me.Backdrop = if(me.Status = false, ShellRunSelected, ShellRun)
me.Status = not me.Status
return RaiseEvent MouseDown(X, Y)</pre>
<p>Note how, in this case, our implementation of the <code>MouseDown</code> event returns the value returned by the consumer of our subclass instances, called with the <code>RaiseEvent</code> statement. Just remember that returning the <code>True</code> value from this event means that such events will not be propagated further along the Events Chain.</p>
<h2>Putting it all Together</h2>
<p>With this information at hand, and the basic concepts explained, <a href="https://youtu.be/7NYwpdXN-SA">this video</a> (in Spanish) shows how you can join all the needed pieces: pictures, events, definition of already consumed events by the subclass; creating a new very basic control from scratch. Obviously, from this point on, you can find in the available documentation all the information needed to create more complex UI controls based on the Canvas class (WebCanvas or iOSCanvas). The possibilities are limitless!</p>
<p>Other useful topics:</p>
<ul>
<li><a href="https://documentation.xojo.com/topics/user_interface/desktop/desktop_controls/canvas.html">User Guide: Desktop Canvas</a></li>
<li><a href="https://documentation.xojo.com/api/deprecated/canvas.html">Canvas</a>, <a href="https://documentation.xojo.com/api/graphics/graphics.html">Graphics</a> classes</li>
<li><a href="https://documentation.xojo.com/UserGuide:iOS_Canvas">User Guide: iOS Canvas</a></li>
<li><a href="https://documentation.xojo.com/topics/user_interface/web/controls/canvas.html">User Guide: Web Canvas</a></li>
</ul>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others.</em></p>
<p>*<a href="https://www.aprendexojo.com/2016/10/canvas-crea-tus-propios-controles/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Updating Code That Used The Graphics Property</title>
		<link>https://blog.xojo.com/2018/12/06/updating-code-that-used-the-graphics-property/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 06 Dec 2018 20:54:35 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5224</guid>

					<description><![CDATA[Starting with Xojo 2018r3, this Graphics property was removed from Window and Canvas so if you had code that was still relying on it, that code will no longer compile. Here are some tips on how you can migrate your code to use the Paint event handlers and tell the Canvas to update with a call to Invalidate.]]></description>
										<content:encoded><![CDATA[<p>Prior to Xojo 2018r3 Window and Canvas both had a Graphics property that you could access and draw to. This was <a href="https://documentation.xojo.com/Resources:Deprecations">deprecated</a> in 2011 because it had significant performance issues on all platforms. The preferred way to draw your graphics since 2011 has been to use the <a title="Window.Paint" href="http://documentation.xojo.com/api/deprecated/window.html#window-paint">Window.Paint</a> or <a title="Canvas.Paint" href="http://documentation.xojo.com/topics/user_interface/desktop/desktop_controls/canvas.html#canvas-paint">Canvas.Paint</a> event handlers and the supplied parameter <i>g As Graphics</i>.</p>
<p>Starting with Xojo 2018r3, this Graphics property was removed from Window and Canvas so if you had code that was still relying on it, that code will no longer compile. Here are some tips on how you can migrate your code to use the Paint event handlers and tell the Canvas to update with a call to Invalidate.</p>
<p><span id="more-5224"></span></p>
<p>If your code was simple and just drawing a Picture to the Graphics property, then you would just move the code to the Paint event handler. For example, this code is drawing a picture:</p>
<pre>Canvas1.Graphics.DrawPicture(MyPic, 0, 0)</pre>
<p>Where that code existed, you would tell it to redraw Canvas1:</p>
<pre>Canvas1.Invalidate(False)</pre>
<p>And then in the Canvas.Paint event handler you would draw the picture:</p>
<pre>g.DrawPicture(MyPic, 0, 0)</pre>
<p>Related to this is another thing to keep in mind. Do not use this Graphics object (g) outside the lifetime of the Paint event. You can certainly pass the Graphics parameter from the Paint event to other methods, but you should not keep a reference of it in a property or elsewhere. When the Paint event eventually completes, this Graphics object is no longer valid and the copy you&#8217;ve saved in a property also becomes invalid. Attempting to use a saved Graphics object outside of the Paint event&#8217;s lifetime may raise an exception in future versions of Xojo.</p>
<p>For more information and other strategies to handle more advanced situations, refer to the topic in the documentation: <a href="http://documentation.xojo.com/topics/graphics/updating_code_that_used_the_graphics_property.html">Updating Code That Used the Graphics Property</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Drawing Objects in a Canvas with the Paint Event</title>
		<link>https://blog.xojo.com/2018/11/02/drawing-objects-in-a-canvas-with-the-paint-event/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 02 Nov 2018 16:28:21 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5102</guid>

					<description><![CDATA[The Canvas control is a great way to draw pretty much anything to a window. With a Canvas, do all your drawing in its Paint event handler for the best quality and performance.]]></description>
										<content:encoded><![CDATA[<p>The Canvas control is a great way to draw pretty much anything to a window. With a Canvas, do all your drawing in its Paint event handler for the best quality and performance.</p>
<p>I&#8217;ve had many people ask for an example for how to create a Canvas that allows you to:</p>
<ul>
<li>Draw pictures within it (as objects)</li>
<li>Move these objects</li>
<li>Remove them</li>
<li>Add labels to them</li>
<li>Programmatically select one</li>
</ul>
<p>This example demonstrates how to do all these things. It has a large Canvas on the window with several buttons that let you add and manage the objects on the Canvas.</p>
<p><span id="more-5102"></span></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5108" src="https://blog.xojo.com/wp-content/uploads/2018/11/2018-11-01_17-22-59.png" alt="" width="800" height="622" /></p>
<p>Use the SegmentControl to select the type of object you want to add to the Canvas and click the Add Object button.  You can optionally specify text to label the object using the field below the button.</p>
<p>Add as many objects as you want. You can click to select an object and it will have a black border drawn around it. You can drag any object within the Canvas.</p>
<p>The other buttons center or remove a selected object.  You can use the Select Object # button to select the object number you specify (objects are numbered starting at 0).</p>
<h2>About the Project</h2>
<p>The concept is pretty simple. Essentially you have a class that represents objects to draw on the Canvas and that knows how to draw itself on a Canvas.</p>
<p>In this project, the <b>CanvasObject</b> class represents an object to draw on the Canvas. It contains everything it needs to know to draw itself, such as its coordinates, label text, the icon to display and other properties.</p>
<p>The <b>ObjectContainerCanvas</b> class is a subclass of Canvas that is responsible for all the drawing, moving and removing of CanvasObjects. This class has an array of CanvasObjects that it knows about. The objects in this array are drawn by the Canvas Paint event handler when appropriate by calling the Draw method on the object itself.</p>
<p>To allow you to drag an object within the Canvas, the MouseDrag event handler is used. It knows what the currently selected CanvasObject is and as you drag the mouse, it updates the coordinates for the CanvasObject.</p>
<p>When the Canvas is told to update itself, usually through a call to Invalidate, the Paint event is called. Here each CanvasObject in the array is drawn on the screen.  This is the Paint event:</p>
<pre>If Background &lt;&gt; Nil Then
  g.DrawPicture(Background, 0, 0)
End If

For Each co As CanvasObject In mCanvasObjects
  co.Draw(g)
Next</pre>
<p>The CanvasObject&#8217;s Draw method draws itself at its coordinates and also draws a selection rectangle around itself if it is selected. This is the Draw method:</p>
<pre>// Draws the object on the canvas.
g.DrawPicture(Image, Left, Top)

If Selected Then
  Const kBorder = 2
  // Draw selection rectangel around the image
  g.PenHeight = kBorder
  g.PenWidth = kBorder
  g.ForeColor = TextColor
  g.DrawRect(Left - kBorder, Top - kBorder, Width + kBorder * 2, Height + kBorder * 2)
End If</pre>
<p>In addition, ObjectContainerCanvas has two events that are called when an object is selected (ObjectSelected) and when an object is moved (ObjectMoved).</p>
<p><a href="http://files.xojo.com/BlogExamples/ObjectsInCanvas.zip">Download the ObjectsInCanvas example</a>.</p>
<p>Check out the other methods on ObjectContainerCanvas that are used to add, move, remove and select objects. I hope you find this technique useful in your projects.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tutorial: Saving WebCanvas Images to Disk</title>
		<link>https://blog.xojo.com/2018/10/11/tutorial-saving-webcanvas-images-to-disk/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 11 Oct 2018 10:00:34 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AprendeXojo]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebCanvas]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5024</guid>

					<description><![CDATA[The WebCanvas control is used for drawing graphics in web apps. It takes advantage of the HTML5 Canvas making it fast and powerful. Sometimes is can be useful to be able to save the graphics drawn in the WebCanvas to an image file, but unfortunately there is no built-in Xojo method to do this. However, by using a little JavaScript you can easily add this capability to Xojo.]]></description>
										<content:encoded><![CDATA[<p>The <strong>WebCanvas</strong> control is used for drawing graphics in web apps. It takes advantage of the HTML5 Canvas making it fast and powerful. Sometimes is can be useful to be able to save the graphics drawn in the WebCanvas to an image file, but unfortunately there is no built-in Xojo method to do this.</p>
<p>However, by using a little JavaScript you can easily add this capability to Xojo.</p>
<p><span id="more-5024"></span></p>
<p>In order to follow this tutorial, create a new <b>Web</b> project and add a new <a href="http://developer.xojo.com/webcanvas"><b>WebCanvas</b></a> control from the Library to the default Web Page added to the project: <code>WebPage1</code>. With the WebCanvas selected in the Navigator, change its name to <code>cCanvas</code> using the Inspector and add the <code>Paint</code> Event Handler to it using the <code>Insert &gt; Event Handler</code> option from the menu. Use the following code to draw a black colored rectangle:</p>
<pre>g.FillRect 0, 0, g.Width, g.Height</pre>
<p>Obviously, you can draw anything you want in the WebCanvas or even <em>paint</em> a picture on it. The achieved result will be the same. For example, we can draw a picture added to our project (with the filename &#8220;landscape&#8221;), using this line of code in the Paint event of our <code>cCanvas</code> instance:</p>
<pre>g.DrawPicture landscape, 0, 0, g.Width, g.Height</pre>
<h2>Retrieving the WebCanvas image data</h2>
<p>The first interesting step is retrieving the underlying image represented by the WebCanvas and that is something we can get using a fragment of <b>JavaScript</b> code executed from the Xojo side. This is the process we will execute from the <code>Action</code> Event Handler of a <b>WebButton</b> added to the <code>WebPage1</code> from the Library. In fact, this will be the button in charge of calling the process to save the image as a picture file on the user disk.</p>
<p>Once the WebButton has been added to the WebPage from the Library, put the following code in its <code>Action</code> Event Handler:</p>
<pre>Dim js() As String
js.Append "var canvas = document.getElementById('" + cCanvas.ControlID + "_canvas');" // We get the item reference based on its ID
js.Append "var img = canvas.toDataURL(""image/png;base64;"");" // We access to the image data, encoded as a base64 string
js.Append "document.location.hash=img" // We assign that data to the document Hash property, so we can retrieve it from the Xojo side

Dim execute As String = Join(js,"")

ExecuteJavaScript execute // Finally, we execute the JavaScript code</pre>
<p>As you can see, the first line of the JavaScript code is in charge of retrieving the <code>cCanvas</code> reference from the DOM (document object model) of the Web Page. For that, we use the <code>ControlID</code> property on our WebCanvas instance, adding the &#8220;canvas&#8221; appended by Xojo to all these kind of objects when generating the source code for the page.</p>
<p>Once we get the reference to our Canvas instance, the following line of code retrieves the picture content itself and assigns it to the <code>img</code> variable. The <em>trick</em> here is that we retrieve that information in its URL format and, thus, encoded as <b>Base64</b> data that we can assign to other document properties without losing its original meaning.</p>
<p>Then, we assign the data to the document <b>Hash</b> property. This is the property that allows us to jump to other page sections previously tagged. However, we will use this property as a temporary storage container for passing the data between the HTML/JavaScript side of the web page and the Xojo side of our code. Why we do this? Well, because we can add the <b>HashTagChanged</b> Event Handler to the <b>Session</b> object so it will fire every time we change the value of the <code>Hash</code> property and we will be able to retrieve the data from that property.</p>
<h2>Retrieving the image, from the Xojo side</h2>
<p>So, the next step is adding the <code>HashTagChanged</code> event to the <b>Session</b> object of our example project, writing the following snippet of code in the associated Code Editor:</p>
<pre>Dim data As String = DecodeBase64(Hashtag.NthField(",",2) ) // We retrieve the information saved in the Hash, but just the relevant data for the image and not the URL part.
wp = New WebPicture(data,"My_Picture.png") // We create a new WebPicture instance using the previously retrieved image data in the constructor, and giving a default file name for the image
wp.ForceDownload = True // We want to force the file download instead of showing it
ShowURL wp.URL // and finally we start the file download process.

Hashtag = "" // Let's empty the hash property, just to make sure that the event will fire even if the WebCanvas doesn't change its contents</pre>
<p>As you can see, in the first line of code we retrieve the image data. We do that using the <code>NthField</code> command because we are only interested in the image data and not in the URL information that precedes it. In addition, we decode the previously encoded data as Base64, so we really get the bytes of the image in PNG format.</p>
<p>Once we get the picture data, we can use any of the available constructors for the <a href="http://developer.xojo.com/webpicture"><b>WebPicture</b></a> class; in this case the one that lets us create a new image from the passed data. In addition, we use this class because it is a subclass of <b>WebFile</b>, and that means that it is simpler to force the download as an image file instead of showing its contents in a new web page.</p>
<p>In fact, this is what we achieve setting the <code>ForceDownload</code> property to <code>True</code>, so when in the following line we use <code>ShowURL</code> we will be forcing the download of the file instead of displaying the image as a new page in the browser. Goal achieved!</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-5027 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/10/WebCanvasToFile.png" alt="" width="500" height="279" /></p>
<h2>Download persistence</h2>
<p>You probably noted that the <code>wp</code> variable is not declared in the previous fragment of code. This is because we need to make sure that the object it points to is in scope during the file downloading process and won&#8217;t get destroyed once we exit the Event Handler (we would want a message error from the web browser in that case). The solution is pretty easy &#8211; we only need to add a new property to our <b>Session</b> object, using the following values:</p>
<ul>
<li><b>Name</b>: wp</li>
<li><b>Type</b>: WebPicture</li>
<li><b>Scope</b>: Private</li>
</ul>
<p>Now, every time you run the app web and click the button, you&#8217;ll see how the web browser downloads the WebCanvas image as a PNG file to disk.</p>
<p>To summarize, in this tutorial we have seen a way to &#8220;communicate&#8221; between the data generated executing JavaScript code in our web app so we can retrieve and use it from the Xojo side of our Web App; in this case applied to the retrieval and saving of the underlying picture represented by a WebCanvas object.</p>
<p>*Watch a <a href="https://www.youtube.com/watch?time_continue=29&amp;v=RTBuub8Atjw">video of this Tutorial in Spanish</a></p>
<p>*<a href="https://www.aprendexojo.com/2016/06/crear-servicio-web-con-xojo/">Read this Tutorial in Spanish</a></p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 8 &#8211; JumpStart App Launcher</title>
		<link>https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 10 Aug 2018 10:10:46 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Atari]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[ContainerControl]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[UI]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4815</guid>

					<description><![CDATA[Replicating an app launcher he originally made for the Atari, Paul's JumpStart app for week 8 of #JustCode demonstrates save/load JSON, ContainerControl and Canvas-based Buttons in Xojo.]]></description>
										<content:encoded><![CDATA[<p>A long, long time ago (1989) one of the first apps I ever made was an app launcher for the Atari ST. I called it JumpSTART. I originally wrote it in <a href="https://en.wikipedia.org/wiki/GFA_BASIC">GFA BASIC</a> and then later re-implemented it in <a href="https://en.wikipedia.org/wiki/Pascal_(programming_language)">Pascal</a> (<a href="https://archive.org/details/OSSPersonalPascal">OSS Personal Pascal</a>, technically).</p>
<p>When I got my first modem I went online with <a href="https://en.wikipedia.org/wiki/GEnie">Genie</a> and <a href="https://en.wikipedia.org/wiki/Delphi_(online_service)">Delphi</a> and uploaded JumpSTART as freeware. Even though it was freeware, I got a few checks in the mail from people that liked it.</p>
<p>I was reminded of JumpSTART when I saw my dock getting crowed. I thought replicating JumpSTART in Xojo would be a good project for week 8 of #JustCode. Though let&#8217;s just call it JumpStart this time around.</p>
<p><span id="more-4815"></span></p>
<p>This is what JumpSTART looked like on monochrome 640&#215;480 screen:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4816 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-09_14-06-09.png" alt="" width="640" height="434" /></p>
<p>JumpStart in Xojo is greatly simplified and looks like this:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4817 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-09_14-10-06.png" alt="" width="680" height="392" /></p>
<p>The Xojo version automatically saves and loads the apps you&#8217;ve added so there was no need for separate Load/Save, Re-Read buttons. Technically they don&#8217;t have to be apps as even a document file can be launched as well.</p>
<p>You can right-click on an app button after you&#8217;ve added it to Rename, Change or Clear it so that also removed the need for some UI controls. And you just click on an empty button to add an app to it. When you click on a button with an app assigned, the app is launched and JumpStart hides itself.</p>
<p>This Xojo app demonstrates the use of a Canvas-based button, ContainerControls added dynamically to a window, and saving/loading JSON. The Canvas-based button will let me tweak the display, colors and maybe display an icon there.</p>
<p>You can <a href="http://files.xojo.com/JustCode/JumpStart.xojo_binary_project.zip">download the project</a> or <a href="https://gitlab.com/xojo/JumpStart">check it out on GitLab</a>.</p>
<p>As an added code treat, I&#8217;ve posted the <a href="https://github.com/paullefebvre/JumpSTART-AtariST">original JumpSTart Pascal code to GitHub</a>. FWIW, the original Pascal source is just over 1300 lines of code. The Xojo version is about 180.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49298-just-code-challenge-week-8-projects">week 8 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 6 &#8211; Bubble Popper</title>
		<link>https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 10:00:59 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Challenge]]></category>
		<category><![CDATA[Games]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4568</guid>

					<description><![CDATA[For this week&#8217;s app, I created a simple iOS app where you tap on &#8220;bubbles&#8221; to pop them. This was actually suggested to me by&#8230;]]></description>
										<content:encoded><![CDATA[<p>For this week&#8217;s app, I created a simple iOS app where you tap on &#8220;bubbles&#8221; to pop them. This was actually suggested to me by Dana Brown some time ago as something that would make a great diversion for her son. I have found it helpful with some of my younger nieces and nephews.</p>
<p>This iOS app demonstrates the use of a Canvas and the detection of taps. When all the bubbles have been popped, more are added. It never ends!</p>
<p><span id="more-4568"></span></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4580 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/07/2018-07-19_09-59-13.png" alt="" width="392" height="770" /></p>
<p><a href="http://files.xojo.com/JustCode/BubblePopper.zip">Download the project</a> or <a href="https://gitlab.com/xojo/BubblePopper">check it out on GitLab</a>.</p>
<p>Enhancements idea include:</p>
<ul>
<li>Add more bubble colors.</li>
<li>Keep track of how many bubbles are popped.</li>
<li>Handle screen rotations so that bubbles that are off screen get repositioned.</li>
<li>Take advantage of multi-touch to allow multiple bubbles to be popped at once.</li>
</ul>
<p>Add your project to the <a href="https://forum.xojo.com/49030-just-code-challenge-week-6-projects">week 6 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 1 &#8211; Color Picker</title>
		<link>https://blog.xojo.com/2018/06/22/just-code-challenge-week1/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 03:50:05 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Challenge]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4358</guid>

					<description><![CDATA[It's the first week of the Just Code challenge so I'm starting with something pretty simple a Color Picker app. This is a desktop app that demonstrates the use of a PushButton, the SelectColor method, a simple Canvas and the Color data type. It has less than 30 lines of code.]]></description>
										<content:encoded><![CDATA[<p>It&#8217;s the first week of the <a href="https://blog.xojo.com/2018/06/18/jump-right-in-just-code-challenge/">Just Code challenge</a> so I&#8217;m starting with something pretty simple. This app lets you choose a color using the system color picker and then shows you the color values in hexadecimal (useful for programming, HTML and CSS), RGB (red, green, blue), HSV (hue, saturation,value) and CMY (cyan, magenta, yellow).</p>
<p><span id="more-4358"></span>This is a desktop app that demonstrates the use of a <a href="http://documentation.xojo.com/api/deprecated/pushbutton.html">PushButton</a>, the <a href="http://documentation.xojo.com/api/deprecated/selectcolor.html">SelectColor</a> method, a simple <a href="http://documentation.xojo.com/api/deprecated/canvas.html">Canvas</a> and the Color data type. It has less than 30 lines of code.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4359 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_11-33-32.png" alt="" width="511" height="194" /></p>
<p>This is the layout of the Window user interface:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4360 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_11-35-10.png" alt="" width="1138" height="689" /></p>
<p>Here you can see the source code that displays the selected color and the related values:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4361" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_11-34-45.png" alt="" width="1138" height="689" /></p>
<p><a href="http://files.xojo.com/JustCode/ColorPicker.xojo_binary_project.zip">Download the Color Picker project source</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Create Your Own ImageWell Based on Canvas</title>
		<link>https://blog.xojo.com/2018/05/07/create-your-own-imagewell-based-on-canvas/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 07 May 2018 10:00:26 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4179</guid>

					<description><![CDATA[Whether you are using Xojo to create your very first application or if you are coming from other languages, like C# or VisualBasic, customized UI controls are probably one of those things you have in your to-do list. For multiplatform Desktop apps, you will find that the Canvas class offers everything you need.]]></description>
										<content:encoded><![CDATA[<p>Whether you are using Xojo to create your very first application or if you are coming from other languages, like <strong>C#</strong> or <strong>VisualBasic</strong>, customized UI controls are probably one of those things you have in your to-do list. For multiplatform Desktop apps, you will find that the <a href="http://developer.xojo.com/canvas"><b>Canvas</b></a> class offers everything you need. In order to show you how easy it can be, follow this tutorial to recreate the <a href="http://developer.xojo.com/imagewell"><b>ImageWell</b></a> UI class control, provided by default in the Xojo framework. Our customized ImageWell will be able to proportionally display any JPEG file dropped by the user on the control, centering it on the available surface.<span id="more-4179"></span></p>
<p>Along the way, we also will see how the Xojo IDE simplifies making subclass properties available from the Inspector Panel, so when using their instances we can set some attributes as the background color, pen size or border color in a more convenient way.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4182 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/04/MyImageWellFinal.png" alt="" width="712" height="534" />As usual, the first step to create a new subclass is adding a new class item to the Desktop project (Insert &gt; Class). With the new class item selected, change its name to something descriptive. For this example we will use <code>MyImageWell</code>. The most important thing here is setting <code>Canvas</code> as its <b>Super</b> attribute. That means that the subclass will be based on the <b>Canvas</b> class, inheriting all its properties, Events and Methods so they will also be available for the subclass.</p>
<p>One of these inherited Events is <b>Open</b>, and we will implement it using the Event Handler option (click the <strong>+</strong> button in the toolbar to access the dropdown menu) in order to inform the class that we want to accept the dropped JPEG files. This is done with the following line of code in the Open Event Handler:</p>
<p><code>Me.AcceptFileDrop("img/jpeg")</code></p>
<p>Obviously, we can extend this support to accept other Xojo compatible graphical formats. For that, we would add a new <a href="http://developer.xojo.com/userguide/using-file-type-sets"><b>File Type Set</b></a> to the project, using it as the filter in the previous line of code.</p>
<p>Once we inform the class that we accept this feature, the next step is implementing the <b>DropObject</b> Event Handler that fires once this action is detected inside the limits of the control. The code we need to write for this Event Handler will test that the <code>obj</code> parameter passed along contains a valid <b>FolderItem</b> and, in that case, we will load such file as a new <b>Picture</b> object, assigning it to a property of the same Type. The code for the event is:</p>
<pre>If obj.FolderItemAvailable Then
  image = Picture.Open(obj.FolderItem)
  Invalidate
End If</pre>
<p>Don&#8217;t forget to add the <code>Image</code> computed property to the Class using Insert &gt; Computed Property while the <code>MyImageWell</code> item is still selected, and using these values:</p>
<ul>
<li><b>Name</b>: Image</li>
<li><b>Type</b>: Picture</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>As you can see, the amount of code we need to load the file as a Picture object and to assign it to the class property is minimal! Why do we use the <b>Invalidate</b> method call afterwards? Well, this is responsible for informing the operating system to redraw the instance when it has a chance. And when this happens it will fire the third and last Event we need to implement: <b>Paint. </b>Here is where we can instruct any Canvas based control how to draw itself through the graphical context represented by the <strong><code>g</code></strong> parameter passed along the Event.</p>
<h2>Painting the control</h2>
<p>Once we&#8217;ve added the <b>Paint</b> Event to the class and before writing the code responible of painting the dropped image inside its limits, we need to add three additional computed properties. We will use them to set some attributes like the color we want to use to paint the control background, the border color and even the width of the border:</p>
<ul>
<li><code>BackGroundColor As Color = &amp;cdddddd</code></li>
<li><code>BorderColor As Color = &amp;c000000</code></li>
<li><code>PenSize as Integer = 2</code></li>
</ul>
<p>Add to the Setter method on every computed property the sentence me.invalidate; so every time we assign a new value to them… the control will be redrawn using the new value (background color, border color, pen size or even a new assigned picture).</p>
<p>The last step is writing the code responsible for drawing the control itself: filling the background with the set color, then drawing proportionally (and centered) the loaded picture pointed by the <code>Image</code> property, and finally drawing the border with the width and color specified. All of this is what we can do using the following snippet of code:</p>
<pre>// We fill the control background using the set color
g.DrawingColor = BackgroundColor
g.FillRectangle(0,0,g.Width,g.Height)

// If we have a valid image object, then we draw it centered and scaled (if necessary)
If image &lt;&gt; Nil Then 
  Var Height, Width As Integer
  Var sourcey, sourcex As Integer = 0 
  If image.Height &gt; image.Width Then
    Height = Me.Height
    Width = (Me.Height * image.Width) / image.Height
    sourcey = (Me.Width - Width) / 2
  Else
    Width = Me.Width
    Height = (Me.Width * image.Height) / image.Width
    sourcex = (Me.Height - Height) / 2
  End If

  // This is the line that actually draws a picture inside the graphic context of our instance
  g.DrawPicture(image,sourcey,sourcex,Width,Height,0,0,image.Width,image.Height)
End If

// We draw the control border
g.PenSize = me.PenSize
g.DrawingColor = BorderColor

g.DrawRectangle(0,0,Me.Width,Me.Height)</pre>
<p>As you can see, the code needed for this is also very simple!</p>
<h2>Make the properties visible from the Inspector Panel</h2>
<p>While we are on it, we can use the <b>Inspector Behavior</b> feature to make our specific properties visible through the Inspector Panel. This way, when we add new instances from the subclass to the layout of any window, we will be able to easily set their values directly from the Inspector Panel. With the <code>MyImageWell</code> item still selected in the Project Browser, use the contextual menu to select the <b>Inspector Behavior</b> option to access the following Window:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4180 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/04/InspectorBehavior.jpg" alt="" width="721" height="459" /></p>
<p>Here you will see all the Class properties, those common to all <b>Canvas</b> derived subclasses and also the ones added for us and that are specific to our class. You can find these properties listed under the <b>Behavior</b> section. To make them visible in the Inspector Panel we just need to check their associated checkboxes; and even modify their default values editing the associated cell if we want to.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4181 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/04/InspectorPanelOwnClass.png" alt="" width="322" height="257" /></p>
<p>Now, we just need to drag and drop the <code>MyImageWell</code> item from the Project Browser into any Window Design Layout in order to add new instances! Once we run the example project, we will see how the controls react to displaying any JPEG picture dropped on it.</p>
<p>If you want, you can investigate deeper into the methods provided by the <a href="http://developer.xojo.com/graphics"><b>Graphics</b></a> class in order to make the control more glittery or more sophisticated.</p>
<p>You can watch <a href="https://www.youtube.com/watch?v=val_Bcgw_4U">this video</a> (en español) to see this in action:</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
<p>*<a href="https://www.aprendexojo.com/2018/04/crea-tu-propio-imagewell-con-canvas/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Improve Your Project&#8217;s Look &#8211; Windows UI Tips</title>
		<link>https://blog.xojo.com/2018/04/18/improve-your-projects-look-windows-ui-tips/</link>
					<comments>https://blog.xojo.com/2018/04/18/improve-your-projects-look-windows-ui-tips/#comments</comments>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 18 Apr 2018 10:00:29 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4126</guid>

					<description><![CDATA[Here are some tips that will help ensure your Windows apps look and feel their best, with Xojo 2018 Release 1 now that Windows apps now have a more stable and flicker-free UI than ever before.]]></description>
										<content:encoded><![CDATA[<p>With Xojo 2018 Release 1 now available, Windows apps now have a more stable and flicker-free UI than ever before. In order to provide these improvements, Xojo and your apps do ask a bit more from Windows. Here are some tips that will help ensure your Windows apps look and feel their best.</p>
<h2>Set Transparent Property for Controls to False</h2>
<p>UI controls now have a Transparent property which determines whether the control is transparent on Microsoft Windows. The default is False for new controls added to layouts. For existing projects and controls, this property is set to True for maximum compatibility.<br />However, controls that have Transparent set to True require more drawing, use more memory and are thus slower. For best results you should set the Transparent property to False for as many controls as possible.</p>
<h2>Consider ContainerControl DoubleBuffer Property</h2>
<p>Set this property to True to reduce flicker on Microsoft Windows when the ContainerControl is scrolled. Otherwise you can leave this to False.</p>
<h2>Avoid Overlapping Controls</h2>
<p>The easiest thing you can do to prevent flickering is to not overlap any controls. Overlapped controls result in more requests to redraw the controls which can result in flickering and slower performance.</p>
<h2>Use a Canvas</h2>
<p>For best results, display any graphics using the Paint event of a Canvas control. Stay away from using the Window Backdrop property, the Window Paint event, the Canvas.Backdrop property or the ImageWell control. Although those techniques work fine in certain situations, they often lead to flickering in more complex window layouts.</p>
<p><del>On the Canvas, the first thing you want to do is turn off the EraseBackground property. The EraseBackground property prevents the Canvas from being erased (and showing as a white rectangle) before it is redrawn, which is another common source of flicker</del>. (<a href="https://documentation.xojo.com/api/deprecated/canvas.html.EraseBackground">Deprecated</a> in Xojo 2019r2) You should also check your usage of the DoubleBuffer property. In many cases you will find you can leave it set to off (False) for best performance.</p>
<p>With these tweaks, you can do all your drawing in the Paint event using the supplied graphics object parameter: g.</p>
<p><strong>Note: Do not do any drawing directly to the Canvas.Graphics property.</strong> This ability was deprecated in 2011 and is strongly discouraged. Drawing in this manner will likely increase flickering and will definitely slow down graphics updates.</p>
<p>You can have separate methods that update the graphics, but they need to be called from the Paint event with the graphics object supplied to the methods as a parameter. Another technique is to have a Picture property that you use to draw you graphics to and then in the Paint event handler you draw the Picture to the Canvas to display it.</p>
<p>When you want the Canvas to update itself, redrawing any changes to your graphics, you call the Invalidate method:</p>
<pre>Canvas1.Invalidate(False)</pre>
<p>You can also call the Refresh method:</p>
<pre>Canvas1.Refresh(False)</pre>
<p>The difference is that Invalidate tells the Canvas to update itself when it gets a redraw request from the operating system. The Refresh method tells the Canvas to update itself immediately. Normally you want to use Invalidate as it results in fewer draw requests, improving performance and reducing flicker.</p>
<p>To reduce flicker, both of the above commands pass False for the EraseBackground parameter (which defaults to True) so that the Canvas is not erased before its updated contents are drawn.</p>
<h2>Remove or Update Older Code</h2>
<p>If you previously had specialized code in your app to help minimize Windows flicker, you should consider removing it as the code may prove to be unnecessary and cause worse performance.</p>
<h2>A Note About Virtual Machines</h2>
<p>Many people run Windows in Virtual Machines. If you do so you&#8217;ll want to ensure that you have the best performance possible. Xojo apps use Direct2D for all screen drawing and not all VM software has properly accelerated graphics drivers for this.</p>
<p>In particular, VMware Fusion has rather poor performance when &#8220;Accelerate 3D Graphics&#8221; is enabled in the Display preferences. For best performance you should make sure that option is turned off.</p>
<p>Alternatively, Parallels Desktop and VirtualBox both seem to have better graphics performance with Direct2D and Xojo apps.</p>
<p>For more information:</p>
<ul>
<li><a href="http://developer.xojo.com/windows-ui-guidelines">Windows UI Guidelines</a></li>
</ul>


<p>*Minor update re: deprecation 3/2021</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.xojo.com/2018/04/18/improve-your-projects-look-windows-ui-tips/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
