<?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>WebCanvas &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/webcanvas/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 02 Mar 2021 18:42:50 +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>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 fetchpriority="high" 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 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 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>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>
	</channel>
</rss>
