<?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>Xojo API 2.0 &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/api-2-0/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, 18 Aug 2025 20:41:29 +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>Xojo Web Evolves: What’s Here in 2025r1?</title>
		<link>https://blog.xojo.com/2025/03/25/xojo-web-evolves-whats-here-in-2025r1/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:31:35 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14678</guid>

					<description><![CDATA[What happens when Xojo Web adds drag and drop support, supercharges WebListBox, and packs in 40+ changes? Let’s find out! Drag and Drop Support The&#8230;]]></description>
										<content:encoded><![CDATA[
<p>What happens when Xojo Web adds drag and drop support, supercharges WebListBox, and packs in 40+ changes? Let’s find out!</p>



<h2 class="wp-block-heading"><strong>Drag and Drop Support</strong></h2>



<p>The biggest thing this time is that we&#8217;ve added general drag and drop support for web. From now on, any visual control can be dragged or accept drops.. That includes controls created using the Web SDK, allowing you (and third-party developers!) to increase the user experience on your web projects.</p>



<p>Now, imagine new ways of updating a Database application. For example, creating a &#8220;Form Builder&#8221;, a full &#8220;Website Builder&#8221; or even a &#8220;Database Schema&#8221; web application where the user can drag elements from a library and drop them into the editor. Are you scheduling posts on social networks using a WebDatePicker? What about using a calendar view with drag and drop support?</p>



<p>We&#8217;ve included a drag and drop Kanban board example. Take a look at <a href="https://blog.xojo.com/2025/03/25/building-a-web-kanban-board-gui-with-drag-drop-support/">the blog post</a> to learn more about it.</p>



<figure class="wp-block-video"><video height="1410" style="aspect-ratio: 1854 / 1410;" width="1854" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo-1.mp4"></video></figure>



<p>How cool is that?</p>



<p>While drag and drop can make your app easier to work with for some users, it can also be an accessibility barrier for other users. Just remember to offer an alternative way for interacting with your application. In a full featured Kanban app, for example, the user should still be able to change the status of a task from the task details screen, using a regular WebPopupMenu (or any other accessible method)</p>



<h2 class="wp-block-heading"><strong>WebListBox Updates</strong></h2>



<p>Speaking of dragging things, WebListBox also now supports reordering rows using the mouse. Just enable the new Allow Row Reordering property (which is Off by default) and you are all set.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="676" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1024x676.png" alt="" class="wp-image-14680" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1024x676.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-300x198.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-768x507.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1536x1014.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-2048x1352.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>This can also be set programmatically at runtime with AllowRowReordering. Once the user finishes a reorder, the RowsReordered event is called, allowing you to persist the changes in your database, for example.</p>



<figure class="wp-block-video"><video height="1034" style="aspect-ratio: 1320 / 1034;" width="1320" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/Grabacion-de-pantalla-2025-03-13-a-las-12.06.45.mp4.mp4"></video></figure>



<p>Another requested feature was to allow users to perform inline edits. <a href="https://documentation.xojo.com/api/user_interface/web/weblistbox.html#">WebListBox</a> received some new methods and events to handle this:</p>



<ul class="wp-block-list">
<li><strong>ColumnTypeAt:</strong> To make a whole column editable</li>



<li><strong>CellTypeAt:</strong> To override the ColumnTypeAt on specific cells</li>



<li><strong>EditCellAt:</strong> A method you can use to begin the edit on specific cells</li>



<li><strong>CellAction Event:</strong> Allowing you to persist the changes made by the user</li>
</ul>



<p>This is also supported when using a WebDataSource.</p>



<p>And not only are TextField and TextArea supported, CheckBox is also part of the WebListBox.CellTypes enumeration, to match what DesktopListBox supports:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="794" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-1024x794.png" alt="" class="wp-image-14682" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-1024x794.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-300x233.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-768x596.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16.png 1318w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Last, but not least, we&#8217;ve decided to split CellTextAt into two different methods. Until now, you could get and set the caption of a cell using CellTextAt, but also a WebListBoxCellRenderer. This could cause trouble because a Variant was being returned, that could be either a String or a WebListBoxCellRenderer so, when not being used carefully, it could raise IllegalCastException at runtime.</p>



<p>From now on, CellTextAt will only support String. If you want to get or set a cell renderer, you will have to use CellRendererAt instead. This makes the API more obvious.</p>



<p>If you were using CellTextAt for getting and setting cell renderers, you will need to update your code to use CellRendererAt instead.</p>



<h2 class="wp-block-heading"><strong>Wrapping Up</strong></h2>



<p>This release empowers Xojo Web projects to meet more user needs, no JavaScript required. Drag and drop finally joins the party, filling a critical gap from the old Web 1 framework.</p>



<p>Be sure to dig into the <a href="https://documentation.xojo.com/resources/release_notes/2025r1.html#">release notes</a>, as 2025r1 packs over 40 changes for the web target alone.</p>



<p>I’d love to hear how you’re weaving these updates into your projects! Drop some screenshots or screen recordings in a new forum thread or shoot me a private message if you prefer.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</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>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo-1.mp4" length="710061" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/Grabacion-de-pantalla-2025-03-13-a-las-12.06.45.mp4.mp4" length="378839" type="video/mp4" />

			</item>
		<item>
		<title>The Power of Transactions in SQLite with Xojo</title>
		<link>https://blog.xojo.com/2024/06/12/the-power-of-transactions-in-sqlite-with-xojo/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Wed, 12 Jun 2024 16:06:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13056</guid>

					<description><![CDATA[SQLite is a powerful, serverless database engine widely used in various applications. Transactions in SQLite play a crucial role in ensuring data integrity and consistency.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>SQLite is a powerful, serverless database engine widely used in various applications. Transactions in SQLite play a crucial role in ensuring data integrity and consistency. In Xojo, SQLiteDatabase.BeginTransaction, SQLiteDatabase.CommitTransaction, and SQLiteDatabase.RollbackTransaction provide easy ways to manage transactions.</p>



<h2 class="wp-block-heading">What are Transactions?</h2>



<p>A transaction is a sequence of SQL commands executed as a single unit, adhering to the <a href="https://en.wikipedia.org/wiki/ACID">ACID</a> properties:</p>



<ul class="wp-block-list">
<li>Atomicity: All or none of the changes are applied.</li>



<li>Consistency: The database remains in a valid state.</li>



<li>Isolation: Concurrent transactions do not interfere with each other. </li>



<li>Durability: Once committed, changes are permanent.</li>
</ul>



<h2 class="wp-block-heading">Basic Transaction Commands</h2>



<p>SQLite supports three main commands for transactions:</p>



<ul class="wp-block-list">
<li>BEGIN TRANSACTION: Starts a new transaction.</li>



<li>COMMIT: Finalizes changes and makes them permanent.</li>



<li>ROLLBACK: Reverts changes made since the last BEGIN TRANSACTION. </li>
</ul>



<h3 class="wp-block-heading">Sample in Xojo</h3>



<p>Let’s consider a banking application where money is transferred between accounts. Without transactions, inconsistencies might occur. For example, if the first update (deducting money from one account) succeeds but the second update (adding money to another account) fails, the database will be left in an inconsistent state, reflecting a transfer that didn’t fully happen. Using transactions ensures that both updates either succeed or fail together, maintaining consistency. </p>



<pre id="xojo" class="wp-block-code"><code>Var db As New SQLiteDatabase
db.DatabaseFile = FolderItem.ShowOpenFileDialog("bank.db")
If db.Connect Then
  Try
    db.BeginTransaction
    db.ExecuteSQL("UPDATE accounts SET balance=balance-100 WHERE account_number=123")
    db.ExecuteSQL("UPDATE accounts SET balance=balance+100 WHERE account_number=456")
    db.CommitTransaction
  Catch e As DatabaseException
    db.RollbackTransaction
    MessageBox("Transaction failed: " + e.Message)
  End Try
Else
  MessageBox("Failed to connect to the database")
End If</code></pre>



<p>In this example, BeginTransaction starts the transaction. The UPDATE commands perform the transfer. If successful, CommitTransaction finalizes the changes. If an error occurs, RollbackTransaction reverts all changes.</p>



<h2 class="wp-block-heading">Advanced Transaction Control</h2>



<p>SQLite also offers advanced transaction modes: DEFERRED, IMMEDIATE, and EXCLUSIVE.</p>



<ul class="wp-block-list">
<li>DEFERRED: Default mode, acquires a write lock only when the first write operation occurs.</li>



<li>IMMEDIATE: Acquires a write lock immediately upon transaction start. </li>



<li>EXCLUSIVE: Prevents all other read and write operations during the transaction.</li>
</ul>



<p>Choosing the transaction type depends on the application’s specific requirements. DEFERRED balances concurrency and consistency, while IMMEDIATE and EXCLUSIVE provide higher isolation at the cost of concurrency.</p>



<h3 class="wp-block-heading">Example of Advanced Transaction</h3>



<pre id="xojo" class="wp-block-code"><code>If db.Connect Then
  Try
    db.ExecuteSQL("BEGIN IMMEDIATE TRANSACTION")

    ' Perform read and write operations here

    db.CommitTransaction
  Catch e As DatabaseException
    db.RollbackTransaction
    MessageBox("Transaction failed: " + e.Message)
  End Try
Else
  MessageBox("Failed to connect to the database")
End If</code></pre>



<p>In this example, an IMMEDIATE transaction ensures exclusive access from the start.</p>



<h2 class="wp-block-heading">Transaction Speed Considerations</h2>



<p>The speed of transactions in SQLite can be influenced by various factors:</p>



<ul class="wp-block-list">
<li>Batching Operations: Grouping multiple operations in a single transaction can significantly improve performance.</li>



<li>Disk I/O: The underlying storage medium and its I/O performance impact transaction speed.</li>



<li>Transaction Type: IMMEDIATE and EXCLUSIVE transactions might be slower due to locking mechanisms but provide higher isolation.</li>
</ul>



<p>Batching multiple operations into a single transaction reduces the overhead of repeatedly acquiring and releasing locks, leading to faster execution.</p>



<h2 class="wp-block-heading">Benefits of Using Transactions</h2>



<p>Using transactions offers numerous benefits:</p>



<ol class="wp-block-list">
<li>Atomicity: Prevents the database from being left in an inconsistent state due to partial updates.</li>



<li>Consistency: Ensures the integrity of the database by transitioning only to valid states.</li>



<li>Isolation: Prevents interference between concurrent transactions. </li>



<li>Durability: Ensures that committed changes are permanent, even in the event of a system failure.</li>
</ol>



<p>By understanding and applying transactions, developers can create robust applications that handle data modifications seamlessly, minimizing the risk of errors and inconsistencies.</p>



<p>Based on the <a href="https://ducklet.app/blog/2024/01/17/the-power-of-transactions-in-sqlite/">Ducklet Blog</a> article. Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Develop Database Apps with Xojo</title>
		<link>https://blog.xojo.com/2023/09/26/develop-database-apps-with-xojo/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Tue, 26 Sep 2023 18:06:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9320</guid>

					<description><![CDATA[After you have designed your interface and begun coding, your next step may be to connect to a database. This blog post tells you the databases supported by Xojo, shows you where to find code samples and examples, plus tutorials and videos that walk you through connecting, updating, querying and managing database, plus, an introduction to Xojo's new DBKit. Get the resources and knowledge you need to get your first database project off the ground today.]]></description>
										<content:encoded><![CDATA[
<p>After you have designed your interface and begun coding, your next step may be to connect to a database. This blog post tells you the databases supported by Xojo, shows you where to find code samples and examples, plus tutorials and videos that walk you through connecting, updating, querying and managing a database, plus, an introduction to Xojo&#8217;s new DBKit. Get the resources and knowledge you need to get your first database project off the ground today.</p>



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



<h3 class="wp-block-heading">Database Support</h3>



<p>Xojo works with a wide variety of databases. SQLite is bundled with your Xojo license and is a great beginner database for desktop, web and mobile apps. Xojo includes direct support for SQLite, PostgreSQL and MySQL. Plus, you can use <a href="https://documentation.xojo.com/topics/databases/supported_engines/odbc.html#odbc">ODBC</a> to connect to just about anything else, such as Oracle, MS-SQL Server, Microsoft Access, Firebird or even IBM iSeries.</p>



<h3 class="wp-block-heading">Examples</h3>



<p>To help you get started, there are many examples in the Examples/Databases folder included with the Xojo <a href="https://xojo.com/download/">Download</a>, including examples that connect to each of the supported databases. You can find a <a href="https://documentation.xojo.com/resources/examples.html">breakdown of the examples</a> included in the Examples folder in the Xojo Programming Language Documentation.</p>



<p><a href="http://www.xojo.com/blog/en/assets_c/2014/07/DBExamples-429.php"></a>Additionally, you can check out the <a href="https://demos.xojo.com/#customerID">Eddie’s Electronics</a> sample app (located in Examples/Sample Applications/EddiesElectronics) to see how to share database code between Xojo desktop and Xojo web apps.</p>



<p>DBKit is an example project designed to make it easier to build desktop and web applications that are front-ends to databases. Specifically, DBKit makes it easy to connect a database table to the user interface controls on a layout. DBKit also handles a lot of the interface for you.&nbsp;You can read more about <a href="https://documentation.xojo.com/topics/databases/dbkit.html">DBKit</a> in the Xojo Documentation.</p>



<h3 class="wp-block-heading">Read: Documentation</h3>



<p>After you have reviewed the examples, the <a href="https://documentation.xojo.com/topics/databases/database_basics_for_beginners.html">Database Overview</a> in the Xojo Documentation will help with next steps. Remember, Xojo comes bundled with SQLite which is an excellent database for desktop, web and mobile apps. Read more about using <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/overview.html">SQLite</a> in the Xojo Documentation and check out this <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/sqlite_basics.html">SQLite Tutorial</a> for more detail.</p>



<h3 class="wp-block-heading">Watch: Videos</h3>



<p>The Xojo YouTube channel has hundreds of videos on all things Xojo. Here are the most recent Xojo Database videos and playlists:</p>



<ul class="wp-block-list">
<li>Video: <a href="https://youtu.be/GGyu4D0ni28">Connecting to a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/JWja37wXz2U">Updating a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/8ENtgkzvyS0">Querying a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/wVHYk-4XG2o">Managing the UI when Updating a Database</a></li>



<li>Video: <a href="https://youtu.be/3Jjf1Xrnm2w">Using DBKit to easily connect databases to Xojo applications</a></li>



<li>Playlist: <a href="https://www.youtube.com/playlist?list=PLPoq910Q9jXhRoPw0_mHKdVUKPXpL9TKV">Using Databases with Xojo</a> &#8211; A growing, catch-all playlist for videos related to Xojo and databases.</li>



<li>Playlist: <a href="https://www.youtube.com/playlist?list=PLPoq910Q9jXjDBrL3KymUwnagM8d7Xbia">Xojo and SQLite</a> &#8211; SQLite comes bundled with Xojo and is a great database for beginners building desktop, web and mobile apps with Xojo.</li>
</ul>



<h3 class="wp-block-heading">Vendor Documentation</h3>



<p>Lastly, you should always refer to the vendor-specific documentation for the database you are using to learn the specifics about how that database works, including SQL syntax.</p>



<ul class="wp-block-list">
<li><a href="http://www.sqlite.org/docs.html">SQLite</a></li>



<li><a href="http://www.postgresql.org/docs/">PostgreSQL</a></li>



<li><a href="http://dev.mysql.com/doc/">MySQL</a></li>



<li><a href="http://www.oracle.com/technetwork/indexes/documentation/index.html?ssSourceSiteId=ocomen">Oracle Database</a></li>



<li><a href="http://msdn.microsoft.com/en-us/library/bb545450.aspx">Microsoft SQL Server</a></li>
</ul>



<p>Xojo simplifies the development process, reduces complexity and empowers developers to create efficient and functional database applications with relative ease. The Xojo IDE is free to use for development and testing &#8211; design, develop, run and debug your app all without a license. Purchase a license when you are ready to compile your apps, licenses start at $149. Visit the <a href="https://xojo.com/store/">Xojo Store</a> to find the license right for your project.</p>



<p>If you have questions after you have reviewed these materials, the Xojo <a href="https://forum.xojo.com">Forum</a> is an accessible and essential resource for Xojo users of all levels. You can also <a href="https://www.xojo.com/company/contact.php">contact</a> Xojo directly with your questions.</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>XDC London Announcements &#038; News</title>
		<link>https://blog.xojo.com/2023/04/26/xdc-london-announcements-news/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Wed, 26 Apr 2023 10:33:05 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11506</guid>

					<description><![CDATA[Welcome to London! The 2023 Xojo Developer Conference is underway, starting with the keynote from Xojo Founder and CEO Geoff Perlman. The keynote video will be available shortly on Xojo's YouTube channel so you can watch it on-demand, here is what we have announced so far:]]></description>
										<content:encoded><![CDATA[
<p>Welcome to London! The 2023 Xojo Developer Conference is underway, starting with the keynote from Xojo Founder and CEO Geoff Perlman. The keynote video will be available shortly on Xojo&#8217;s YouTube channel so you can watch it on-demand, here is what we have announced so far:</p>



<h3 class="wp-block-heading">Conference Apps</h3>



<p>The XDC App is available on both iOS and Android for the first time ever! Search &#8216;XDC 2023&#8217; in the <a href="https://play.google.com/store/apps/details?id=com.xojo.xdc2023">Google Play Store</a> or <a href="https://apps.apple.com/app/xdc-2023/id6448080198">iOS App Store</a>. A shoutout and big thank you to Xojo MVPs Martin T and Jérémie Leroy for making these apps. Martin wanted to test out the Android pre-release by developing a real world Android app. Jeremie then used Martin&#8217;s project to create an iOS version in a few days. </p>



<h3 class="wp-block-heading">XDC Videos</h3>



<p>We are pleased to announce that all of the XDC session videos and keynote will be available free on Xojo&#8217;s YouTube channel (<a href="https://youtube.com/playlist?list=PLPoq910Q9jXimWZv2c_KzATfmCvxrtTMX&amp;si=vonb5hkGTCH5v73z">XDC 2023 Playlist</a>). You can <a href="https://www.youtube.com/@XojoInc" target="_blank" rel="noreferrer noopener">subscribe to the YouTube channel</a> to receive notifications when new videos are posted. </p>



<h3 class="wp-block-heading">Bug Bash</h3>



<p>As we announced at the last conference, we are spending two weeks per release cycle working on bug bash type bugs. This means we are looking for bugs that do not meet the regular criteria, so they are old, only affect one person or a small number of people, etc. For Xojo 2023r2 there are already 17 issues of this sort that have been resolved. One of them, for example, was reported twelve years ago. We are committed to focus on bug fixes and will continue to fix these types of bugs during each release cycle. As a reminder, if you have a bug that is a showstopper for you, something you cannot work around, please <a rel="noreferrer noopener" href="https://xojo.com/company/contact.php" target="_blank">contact us</a> &#8211; our technical support team may be able to help you or can escalate it to an engineer.</p>



<h3 class="wp-block-heading">Recent New Features</h3>



<p>In his Keynote, Geoff discussed some recent new features, including <a href="https://blog.xojo.com/tag/pdf/">PDF</a>, the <a href="https://blog.xojo.com/tag/charts/">ChartControl</a>, <a href="https://blog.xojo.com/2023/03/28/filtering-the-debugger/">Filtering the Debugger</a> and more. </p>



<p>DesktopXAMLContainer: This is the foundation for what will be our updated Windows controls. We will start with using the new controls in the Desktop XAML container but in the future they will replace the Win32 controls with modern controls. William will be talking more about this in his session.</p>



<p>Popover Control: A dialog-like layout that can pop-up over the existing layout is in the works.</p>



<p>DatabaseConnection Class: A lot of work has been done to make connecting to databases easier with more on the way.</p>



<p>Xojo Libraries (formerly Xojo Plugins): Using Xojo libraries, you will be able to take some portion of a Xojo project and compile to a library you can distribute or use in your other projects.</p>



<h3 class="wp-block-heading">Sales &amp; Community Growth</h3>



<p>Sales of Xojo licenses continue to grow in 2023! This year-to-date, license renewals are up 10% over the same period last year and new license sales are up 20%.</p>



<h3 class="wp-block-heading">In-Person Events</h3>



<p>Apple, Google and others have moved to mostly online events. And in that same light, Xojo will be focusing more on on-demand events and videos. Given peoples&#8217; comfort and preference for online, on-demand content, we do not plan on having an <a rel="noreferrer noopener" href="https://blog.xojo.com/2023/03/07/no-we-dont-have-plans-for-a-xdc-2024/" target="_blank">XDC 2024</a>.</p>



<h3 class="wp-block-heading">Android</h3>



<p>Xojo Android is currently at 96% completion with only a handful of things remaining. Android will be shipping in the next release of Xojo, 2023r2 (marked as beta). If you have a current Xojo iOS, Pro or Pro Plus license, Android will be included at no additional charge. The iOS license will become a Mobile license and will build for both iOS and Android.</p>



<h4 class="wp-block-heading">Android in the Future</h4>



<p>Initially, you will need to develop separate Android and iOS projects. The end that we are working towards will be a single mobile project that builds for both Android and iOS similar to how Desktop projects build for Mac, Windows an Linux.</p>



<p>Now that we are getting closer to Android shipping, we look forward to more time for us to focus on other things.</p>



<h3 class="wp-block-heading">Artificial Intelligence</h3>



<p>AI may not be on the <a href="https://documentation.xojo.com/resources/roadmap.html#roadmap">roadmap</a> but we are definitely thinking about it. There are some significant gains in the apps and how you create them. If you have input please reach out to us and let us know how you could use AI in your projects, or create a feature request. We are excited to see how the world of development and software in general will change with AI.</p>



<p>The rest of the sessions today will be presented by the Xojo Engineers. We look forward to hearing from Paul, William, Travis and Ricardo. We will keep this blog post updated and will let you all know when the videos are ready to watch! We look forward to the next few days and a great conference!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bootstrap 5 is Coming to the Xojo Web Framework</title>
		<link>https://blog.xojo.com/2023/01/26/bootstrap-5-is-coming-to-the-xojo-web-framework/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Thu, 26 Jan 2023 23:50:06 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web SDK]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11198</guid>

					<description><![CDATA[Bootstrap is the toolkit the Xojo Web framework uses to create the UI controls for your web projects. Bootstrap continues to improve and as a result we are working to upgrade the Web framework to the latest version. We are currently planning to ship this updated Web framework in Xojo 2023r2.]]></description>
										<content:encoded><![CDATA[
<p><a rel="noreferrer noopener" href="https://getbootstrap.com" target="_blank">Bootstrap</a> is the toolkit the Xojo Web framework uses to create the UI controls for your web projects. Bootstrap continues to improve and as a result we are working to upgrade the Web framework to the latest version. We are currently planning to ship this updated Web framework in Xojo 2023r2.</p>



<p>For most Xojo users, this update won&#8217;t require any changes at all to your existing projects. For those that create their own controls using the Web SDK, there will likely be a minor bit of work.</p>



<h2 class="wp-block-heading">Dark Mode Support</h2>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-1024x716.png" alt="" class="wp-image-11199" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284.png 1237w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Eddie&#8217;s Electronics sample app running with Dark Mode support enabled.</figcaption></figure>



<p>The Web framework is currently the only Xojo framework that doesn&#8217;t support Dark Mode. Fortunately,  Bootstrap 5 does. As with Desktop targets, users of your web projects will be able to decide between the light and dark modes. We plan for this to work identically to the way it works for your Desktop projects now. There will be a Supports Dark Mode Build Setting that will be off by default for existing projects and on by default for new ones.</p>



<h2 class="wp-block-heading">More than Dark Mode</h2>



<p>Visually, Bootstrap 5 comes with some subtle changes. For example the blue color it uses is still blue… but not that blue, helping to increase the contrast of your buttons.</p>



<p>You may notice that the buttons are a little bit rounder by default, following the latest design trends.</p>



<p>The look and feel of some input controls, like checkboxes and radio buttons, will be more similar between different browsers and operating systems.</p>



<p>Bootstrap 5 also includes new components and features, like <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/components/accordion/" target="_blank">Accordion</a> and <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/components/offcanvas/" target="_blank">Offcanvas</a>. These may find their way into future releases via the Web framework or from one of the third-party control developers.</p>



<p>Finally, Bootstrap 5 no longer depends on jQuery and it makes use of the latest CSS features which brings us to the next section.</p>



<h2 class="wp-block-heading">Potential Migration Challenges</h2>



<p>We&#8217;ve made it so most Xojo users won&#8217;t need to make any changes to their web projects. For example, we&#8217;ve adapted the Breadcrumb control to look like Bootstrap 4 by default. Generally speaking, if you are using the default theme and you aren&#8217;t using third-party controls, you won&#8217;t need to do anything special.</p>



<p>However, if you are currently using a custom Bootstrap 4 theme that uses a custom bootstrap.min.css file, it may not work properly. If you&#8217;ve downloaded the theme from a website such as <a rel="noreferrer noopener" href="https://bootswatch.com" target="_blank">Bootswatch</a>, you can download an updated Bootstrap 5 compatible theme from the same site. Bootstrap 5 themes are actually easier to find than those for v4.</p>



<p>We are announcing this change to v5 in advance to allow third-party library developers the time to adapt their code and make use of the new Bootstrap 5 HTML and JavaScript API. If you rely upon any third-party controls for your web projects, you will need to upgrade them when new Bootstrap 5-compatible versions become available.</p>



<p>To make the migration as smooth as possible for everyone, we will continue including jQuery and provide independent betas, prior to releasing a version of Xojo with Bootstrap 5.</p>



<p>In the <a href="https://getbootstrap.com/docs/5.3/migration/" target="_blank" rel="noreferrer noopener">Bootstrap 5 Migration Guide</a> you can find an extensive list of changes and improvements since Bootstrap 4.6.</p>



<p>If you have any questions, please feel free to ask on the <a rel="noreferrer noopener" href="https://forum.xojo.com" target="_blank">Forum</a>. Users attending the <a rel="noreferrer noopener" href="https://xojo.com/xdc/london/index.html" target="_blank">Xojo Developer Conference</a> can also meet and talk in person with Xojo engineers, about this or any other topic.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Running Xojo Web projects on Raspberry Pi 64-bit ARM boards</title>
		<link>https://blog.xojo.com/2022/12/13/running-xojo-web-projects-on-raspberry-pi-64-bit-arm-boards/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 15:22:45 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[64-bit]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Raspbian]]></category>
		<category><![CDATA[Remote Debugging]]></category>
		<category><![CDATA[Single Board Computer]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Forum]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11065</guid>

					<description><![CDATA[Xojo 2022r4 opens the door for running projects on 64-bit Raspberry Pi ARM boards. Console, Desktop and Web are supported.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2022r4 opens the door for running projects on 64-bit Raspberry Pi ARM boards. Console, Desktop and Web are supported.</p>



<p>Xojo Web is an excellent way to expose the features of your electronics projects without having to attach any screen to them. It&#8217;s never been easier to build a Web GUI for your smart clocks, drones, POS, domotics, robots or just some automation services. Thinking about building a solar powered server to automate your tweets? Why not!</p>



<p>If you prefer, you can just expose a Web API instead that can be remotely consumed from another device.</p>



<h2 class="wp-block-heading">What Raspberry Pi boards support ARM 64-bit Linux OS?</h2>



<ul class="wp-block-list">
<li>Raspberry Pi Zero 2</li>



<li>Raspberry Pi 3</li>



<li>Raspberry Pi 4</li>



<li>Raspberry Pi 400</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="763" src="https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-zero-2-1024x763.png" alt="" class="wp-image-11066" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-zero-2-1024x763.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-zero-2-300x224.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-zero-2-768x573.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-zero-2.png 1336w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">One of my Raspberry Pi Zero 2, running a 64-bit Xojo Web application.</figcaption></figure>



<h2 class="wp-block-heading">Preparing your Raspberry Pi</h2>



<p>The easiest way to get your operating system ready is by using the <a href="https://www.raspberrypi.com/software/" data-type="URL" data-id="https://www.raspberrypi.com/software/" target="_blank" rel="noreferrer noopener">Raspberry Pi Imager</a>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="690" src="https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-imager-1024x690.png" alt="" class="wp-image-11067" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-imager-1024x690.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-imager-300x202.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-imager-768x518.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/raspberry-pi-imager.png 1510w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Raspberry Pi Imager v1.7.3.</figcaption></figure>



<p>At the moment of writing this article, it selects the 32-bit flavor by default. If you have one of the supported boards, go ahead and try Raspberry Pi OS (64-bit) or Raspberry Pi OS Lite (64-bit). The later won&#8217;t include any desktop environment, you&#8217;ll have to access by SSH.</p>



<p>Select your SD Card storage and press on Write. Optionally, if you want to set a hostname for your board, enable SSH, or even configure your Wifi, press on the gears icon.</p>



<p>In just a few minutes you will have a ready to boot SD card for your Raspberry Pi.</p>



<h2 class="wp-block-heading">Remotely debugging your projects</h2>



<p>This is one of my favorite features of Xojo.</p>



<p>In your Xojo installation Extras folder, you will find a &#8220;Remote Debugger Console&#8221; and &#8220;Remote Debugger Desktop&#8221;, that also works for your Linux 64-bit OS.</p>



<p>Depending on which flavor of Linux you&#8217;ve selected in the previous step, send the Console or Desktop ZIP to your board, run it and configure the settings.</p>



<p>Inside Xojo, go to Preferences and press on the Debugging tab.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="599" src="https://blog.xojo.com/wp-content/uploads/2022/12/xojo-preferences-debugging-1024x599.png" alt="" class="wp-image-11068" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/xojo-preferences-debugging-1024x599.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-preferences-debugging-300x176.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-preferences-debugging-768x449.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-preferences-debugging.png 1480w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Xojo Debugging Preferences panel.</figcaption></figure>



<p>That&#8217;s it. Now you will be able to remotely run and debug your applications. Add a few breakpoints and the execution will stop as soon as it reaches it, allowing you to explore the current state.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="667" src="https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug-1024x667.png" alt="" class="wp-image-11070" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug-1024x667.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug-300x195.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug-768x500.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug-1536x1000.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/12/xojo-remote-debug.png 1910w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Running your project remotely, to debug.</figcaption></figure>



<h2 class="wp-block-heading">Deploying the final version</h2>



<p>Once you&#8217;re ready to build the final version of your application, all the wires attached and components soldered, the last step is to &#8220;Deploy&#8221; your application.</p>



<p>There is a tutorial covering this step in detail: <a href="https://blog.xojo.com/2021/05/28/tutorial-deploying-web-apps-on-linux/" data-type="post" data-id="8552">Deploying Web Apps on Linux</a>.</p>



<p>If you create a Raspberry Pi project, please make sure you open a <a href="https://forum.xojo.com" data-type="URL" data-id="https://forum.xojo.com" target="_blank" rel="noreferrer noopener">Forum thread</a>. The Xojo community loves seeing this kind of projects!</p>



<p>What will you build?</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo IDE: WebListBox Preview</title>
		<link>https://blog.xojo.com/2022/12/13/xojo-ide-weblistbox-preview/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 14:34:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[WebListBox]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11045</guid>

					<description><![CDATA[Xojo 2022r4 includes a much improved WebListBox preview in the Layout Editor. Now you can get a closer look at the control when you project is run in a web browser.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2022r4 includes a much improved <a href="https://documentation.xojo.com/api/user_interface/web/weblistbox.html#weblistbox">WebListBox</a> preview in the Layout Editor. Now you can get a closer, truer look at your control when your project is run in a web browser.</p>



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



<p>Prior to Xojo 2022r4 the preview for WebListBox instances was a mere gray box with a small icon inside. This isn&#8217;t very helpful for visualizing how your design will look when the control is filled with data.</p>



<p>Now, you will get a preview that more closely resembles to the one provided by the ListBox in Desktop projects. That means the WebListBox preview will display the columns adjusted to the provided columns width and also the initial values (if any). Additionally, WebListBox will react to the change of width in the Layout Editor.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="827" src="https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxBefore-1024x827.png" alt="" class="wp-image-11046" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxBefore-1024x827.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxBefore-300x242.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxBefore-768x620.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxBefore.png 1340w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<figure class="wp-block-image is-style-default"><img loading="lazy" decoding="async" width="1024" height="683" src="https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview-1024x683.png" alt="" class="wp-image-11047" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview-1024x683.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview-300x200.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview-768x513.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview-1536x1025.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/12/WebListBoxPreview.png 1960w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This improvement gives you a much better idea on how your WebListBox will look when the app is run in a browser. </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>Linux Joins the Dark Side</title>
		<link>https://blog.xojo.com/2022/12/13/linux-joins-the-dark-side/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 14:33:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11050</guid>

					<description><![CDATA[While we've been hard at working getting Linux ARM 64 support ready for Xojo 2022r4, released earlier today, we also updated Xojo's Linux support for Dark Mode. Color.IsDarkMode now functions properly and our Linux IDE has now officially joined the dark side.]]></description>
										<content:encoded><![CDATA[
<p>While we&#8217;ve been hard at working getting Linux ARM 64 support ready for Xojo 2022r4, released earlier today, we also updated Xojo&#8217;s Linux support for Dark Mode. Color.IsDarkMode now functions properly and our <a href="https://documentation.xojo.com/topics/user_interface/desktop/supporting_dark_mode.html#supporting-dark-mode">Linux IDE</a> has now officially joined the dark side.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="623" src="https://blog.xojo.com/wp-content/uploads/2022/12/LinuxIDEInDarkMode-1024x623.png" alt="" class="wp-image-11051" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/LinuxIDEInDarkMode-1024x623.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/LinuxIDEInDarkMode-300x182.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/LinuxIDEInDarkMode-768x467.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/LinuxIDEInDarkMode.png 1217w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Depending on your flavor of Linux (in this example we&#8217;re using Gnome on Ubuntu 20.04), you can change themes from your Settings/Appearance sidebar:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="625" src="https://blog.xojo.com/wp-content/uploads/2022/12/Settings-1024x625.png" alt="" class="wp-image-11055" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/Settings-1024x625.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/Settings-300x183.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/Settings-768x469.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/Settings.png 1216w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>And for those interested in other themes, you can also change themes at the command line:</p>



<pre class="wp-block-code"><code>gsettings set org.gnome.desktop.interface gtk-theme 'Yaru-dark'</code></pre>



<p>Xojo will be able to determine which themes are dark mode savvy.  Now you are ready to enjoy the dark side of Linux along with Xojo!</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></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>2022: Welcome Back!?</title>
		<link>https://blog.xojo.com/2022/12/13/2022-welcome-back/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 11:00:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Code Assistants]]></category>
		<category><![CDATA[Code Editor]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10967</guid>

					<description><![CDATA[Does anyone else feel like 2022 is the first year in many years where we have gotten back together, in-person, for big events, small get-togethers, travel and even the daily office grind? Whether that is the right thing to have done or not, it seems that is what many of us did in 2022. Though we all tried new things to stay connected over the past few years (Zoom-fatigue anyone?), there's nothing like seeing an old friend after years apart.]]></description>
										<content:encoded><![CDATA[
<p>Does anyone else feel like 2022 is the first year in many years where we have gotten back together, in-person, for big events, small get-togethers, travel and even the daily office grind? Whether that is the right thing to have done or not, it seems that is what many of us did in 2022. Though we all tried new things to stay connected over the past few years (Zoom-fatigue anyone?), there&#8217;s nothing like seeing an old friend after years apart.</p>



<p>Xojo&#8217;s team was all vaxxed-up and so happy to get together in Nashville for #XDC2022. Tennessee&#8217;s Music City was a delightful backdrop for the first in-person Xojo event since 2019. Check out the short highlights <a href="https://youtu.be/t8xpWVL5pEM">video</a> from Nashville and then join us for #XDC2023 in London, UK. You can <a href="http://xojo.com/xdc/london/index.html">register</a> here.</p>



<p>This year the Xojo team and community welcomed a new Xojo engineer, Ricardo Cruz. Ricardo has applied his expertise to advance and improve Xojo Web. To quote one of Xojo&#8217;s engineers, &#8220;Ricardo coming in has been awesome,&#8221; a sentiment echoed on the Forum and the community in Nashville. </p>



<p>Xojo Web has come so far this year. Control reliability has improved, IDE previews have improved and reconnections have really improved. The web framework can now more often reconnect back to the same web session if it still exists. This is one of the things Ricardo is really happy about, &#8220;You can switch to your email app in your mobile, copy something to the clipboard, come back to the web app and it is still there, ready to continue.&#8221; Under the hood, some dependencies received updates, like jQuery. As a user, you don&#8217;t have to do anything, just use the new Xojo version! Try to tell that to another web developer, that&#8217;s sci-fi outside of Xojo. Also, thanks to the community, the memory and CPU usage continues to be improved release after release. &#8220;Honestly from my perspective it is just fun to play with little projects in it because it has really matured,&#8221; says Xojo&#8217;s Director of Engineering, Travis Hill. </p>



<p>Speaking of technical achievements, this year we added two new targets to Xojo: Windows on ARM 64 and Linux on ARM 64. On Windows, you can natively deploy to ARM-based tablets and laptops that run Windows. On Linux, you can deploy to 64-bit Raspberry Pi which can address significantly more RAM than 32-bit versions. </p>



<p>We built the <a href="https://www.xojo.com/cloud/">Xojo Cloud</a> Control Panel with an updated version of Xojo, and thanks to some Web framework improvements the controls now stay more responsive under load. Plus we&#8217;ve added Xojo Cloud servers in Sydney, Australia for web developers in Australia and New Zealand. We also continued improving and testing our upcoming support for Android, which is now feature complete and awaiting some remaining bug fixes before we make it available to everyone.</p>



<p>In addition, we want to brag about a few technical improvements, including the numerous <a href="https://blog.xojo.com/tag/pdf/">PDF updates</a> implemented by Xojo Engineer and now PDF expert, Javier Menéndez. Also there is the option to generate&nbsp;Program Database <a href="https://blog.xojo.com/2022/07/25/what-the-pdb-is-this/">(PDB)</a>&nbsp;files on Windows and improved <a href="https://blog.xojo.com/2022/10/12/improving-multi-monitor-support-on-windows/">multi-monitor support</a> shepherded by Xojo Engineer William Yu. The list goes on: <a href="https://blog.xojo.com/2022/04/05/using-the-new-user-code-assistants-feature/">Code Assistants</a>, <a href="https://blog.xojo.com/2022/04/05/on-device-ios-debugging-in-xojo/">on-device debugging in iOS</a>, new <a href="https://documentation.xojo.com/">Xojo Documentation</a> site, adding <a href="https://blog.xojo.com/2022/01/07/desktop-adding-controls-at-runtime/">Controls at runtime</a>, loading speed faster for big projects, and the time team-Lefebvre built a <a href="https://blog.xojo.com/2022/03/03/a-web-app-to-calculate-combat-rolls-in-twilight-imperium/">web app</a> to Calculate Combat Rolls in Twilight Imperium&#8230;</p>



<p>Inside Xojo we improved a lot too. Besides welcoming Ricardo and his beard to the team, we migrated Xojo&#8217;s bug and feature reporting platform from the internally managed Feedback tool to the much loved <a href="https://tracker.xojo.com">Issues</a>. This has increased productivity, streamlined work flow, made it easier to search and find, comment, edit. The team couldn&#8217;t be happier!</p>



<p>This year also included Xojo&#8217;s first Bug Bash in a long time! During the Bug Bash, Xojo&#8217;s <a href="https://blog.xojo.com/2022/10/12/bountiful-bug-bashing/">Code Editor</a> got some much needed improvements resulting in noticeably faster updates. Plus updates to the Syntax Help Area thanks to Xojo Engineer and retro-computing expert, Paul Lefebvre. Besides the very real smashing of 100 bugs, the bash had the unintended consequence of giving the engineers an opportunity to work on things they don&#8217;t normally work on, giving engineers opportunities to collaborate and better solve things.</p>



<p>All in all, 2022 was a year of forward movement for Xojo. Which has us leaning into 2023 with a lot of excitement and expectation. Our team is committed to continuing to make Xojo the best cross-platform development tool and we thank you for being part of Xojo&#8217;s continued success!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Versatility of Xojo</title>
		<link>https://blog.xojo.com/2022/12/06/the-versatility-of-xojo/</link>
		
		<dc:creator><![CDATA[Jérémie Leroy]]></dc:creator>
		<pubDate>Tue, 06 Dec 2022 16:49:04 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[App Localization]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GraffitiSuite]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Trello]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11006</guid>

					<description><![CDATA[Many people around the world are celebrating the holidays by giving gifts, which means more and more people are organizing Secret Santa events. In November of 2018, Jérémie Leroy had the idea of making a Secret Santa iOS app. 3 years, 32 languages and 6.5 millions downloads later, Jérémie incorporated Xojo Web to improve his highly successful Xojo iOS app. Secret Santa is a prime example of what is possible and how you can leverage your Xojo skills to expand to other platforms when you need to.]]></description>
										<content:encoded><![CDATA[
<p>It is soon time for the end of year festivities. Many people around the world are celebrating the holidays by giving gifts, which means more and more people are organizing Secret Santa events. During these events, members of a group of friends, family, or colleagues will draw names to become someone’s Secret Santa and then give them a holiday gift, usually something fun.</p>



<figure class="wp-block-table aligncenter"><table><tbody><tr><td class="has-text-align-left" data-align="left"><strong>Did you know?</strong></td></tr><tr><td class="has-text-align-left" data-align="left">Secret Santa is known by different names around the world, such as “Amigo Invisible” in Spanish, “Amigo Secreto” in Portuguese, “Тайный Санта” in Russian.</td></tr></tbody></table></figure>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>I first made a desktop Secret Santa app back in 2015 for an event with friends. We were tired of drawing names out of a hat and having couples being paired together. The app I created solved that problem because couples were excluded from offering a gift to each other. And we didn’t need a hat!</p>



<p>In November of 2018, I had the idea of making a <a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8">Secret Santa iOS app</a> so that anyone with an iPhone or iPad could benefit from the same features I had been enjoying for the past 3 years.</p>



<p>The app would need to be easy to use, avoid couples getting matched with each other, send notifications by email without letting the organizer know which pairs were matched, and of course make sure no name would be assigned twice.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM.png" alt="" class="wp-image-11009" width="168" height="352" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM.png 304w, https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM-143x300.png 143w" sizes="auto, (max-width: 168px) 100vw, 168px" /></a></figure>
</div></div>
</div>



<p>After just 8 days of development, the app was ready to ship and sent to the App Store.</p>



<p>Within 5 days, the app had been downloaded from 35 different countries and was my fastest app to reach 1000 downloads!</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh6.googleusercontent.com/U-yY3aE161mfhU3H6k9ODFP4LtuwzFNWzRrvUdRIvs3cLeHG2sydLIDWL1Ic65Lnw9rJvRQ8mGn82ComNHKq2s-pDWIJoGimmA5082pg_IDuI1KCwX9U82FGIkTSFev4LRYR20Tc8Tkgfn9UlL18C2cAraTTFzJKR4Np5fDCtqwc8jDcjeP1D4e2-mPSBg" alt="" width="-43" height="-22"/></figure>
</div>


<p><a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8"></a></p>



<p>Having the app translated to English, French, Italian, and Spanish in the initial release helped to reach more users.</p>



<p>Version 1.1 of the app was released a few days later with German and Portuguese translations.</p>



<p>That’s when I realized that Secret Santa is something extremely common in Latin America. Many families draw names for Christmas so that they can give and receive one big gift instead of smaller trivial gifts for each family member.</p>



<p>Most updates of the app came with new localizations, which really helped in realizing more and more downloads. After 3 years of updates, the app is now available in 32 languages.</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh5.googleusercontent.com/DJt7zuBJxMbga7qB9LWyTwy-ZwnBYIBS4XbqTmOsuBh25vtv3UN1THXY32Z55sxG0arqCOpyKo1ttUT1q7iY5Z0Y1I9XhT8lbv6C_FPMsLPuhAiZ3q0AIdH9RUhBEGiXP4ft3aGzqAyiND3qk7bH4OSXuXNo3jRc4BPFhDmtT5kHLF2w3cgO66QPT6BctQ" alt="" width="895" height="635"/></figure>
</div>


<p>A high quantity of downloads also meant that I received a lot of feedback from users. Many users were happy with the current features, but I started getting feature requests to send the gift pairs by SMS or WhatsApp instead of by email. We all have a parent or grand-parent who isn’t tech-savvy and doesn’t have an email address.</p>



<h2 class="wp-block-heading"><strong>Leveraging the biggest advantage of Xojo &#8211; Sharing code across platforms</strong></h2>



<p>From 2018 until 2022, I had become used to updating the Secret Santa app itself to add new features and new translations while also fixing bugs. This year, I received a message from an unhappy user stating that they really need a wishlist feature and downloaded my app thinking it already had one.</p>



<p>A valid wishlist feature needed to be accessible to anyone with an Internet connection, whether they used a computer, an iPhone, or an Android device.</p>



<p>Using Xojo Web and a coding language I already knew was the obvious choice for this task. Sharing important bits of code from my main iOS project to the web wishlist project was as easy as copy and paste.</p>



<p>As with any Xojo project, copying classes from one project to the other was a real time saver, especially for the API layer required to communicate between Xojo and the online database that holds all the Secret Santa data.</p>



<p>The main difficulty working on a web project came from the UI. Not that Xojo Web’s UI is difficult, but I am so used to designing mobile apps that my brain didn&#8217;t know where to start.</p>



<p>I knew I wanted to display two columns of data:</p>



<ul class="wp-block-list"><li>The user’s wishlist</li><li>The wishlist from the person they are offering a gift to</li></ul>



<p>The layout had to be responsive to be accessible on both mobile and desktop devices.</p>



<p><a href="https://graffitisuite.com">Graffitisuite</a> from Anthony Cyphers came to mind, and within a few minutes of reviewing the online demo, I was convinced to use GraffitiKanban web control. I am a big fan of <a href="https://trello.com">Trello</a> for organizing my work, displaying cards in labeled columns. That&#8217;s exactly what I needed for the wishlist feature.</p>



<p>GraffitiKanban is “responsive” (Web Design term), meaning the display changes to adapt to smaller screens such as mobile devices.</p>



<p>GraffitiSuite also offers a wide variety of UI elements that made me save a lot of time.</p>



<p>7 days after the initial feature request, the wishlist feature was available to all.</p>



<p><strong>Wishlist on a desktop browser:</strong></p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/idkQ031bZaWEyP1Pj4BULLGJRc-Xz95sl4xlCkYD2KZt1IsMKOvsoP9ywwY5f81wwykuMuWqofDIelJNIiwE0j0IcF93ZXyaXFBmVK991oigNXPmi7W6BR1_b44sWWWKkYO7jAXVbjDC6Io4RVwhVveV8oM4Nu1UOPMXzrcxPL-VtdgVNB3bQ58MtolkmQ" alt=""/></figure>
</div>


<p><strong>Wishlist on a mobile browser:</strong></p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/9KZB2JwTAt2cLXTb7Es_G2Qdwldmfa1nMRmS7F2s9Pb2iVuz0e4M5Zj_8XfUn97QTUvU-78i8cDq5JZOrMwr-ROe0ihov1R2YDZSVseEky4KwTATMxU2tQHD6TXQpouL37NXEryK86JjTv36A-N-VHSqCXKXYza6M2V8WyWmP7Wie5kY_0GuMaOeixI0" alt=""/></figure>
</div>


<p>Deploying the app to <a href="https://www.xojo.com/cloud">Xojo Cloud</a> was extremely easy.</p>



<p>A single button press in Xojo, a subdomain DNS record, 2 minutes of configuration in Cloudflare, and the web app was up, running, and accessible through HTTPS.</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/o76SHsHWThArJFy__WCn9HW8rgFJ2Q0lJqq12o3ReAXRszlJe5VESNgYThKLfHtsU2hfOHrm5IbBVOOjCf4n6hjdUaYMZM0vjhfHGOsVmQkugEHbHHInjG29mDEpOk4-Ef8sg98ZTZp1esNIU4JM1jQ4qTZSdxLcrY_YKlOUKCW2_lWqV84NTyp-vvnnJQ" alt=""/></figure>



<p>Customer use of the wishlist feature has blown-up more than I ever would have expected. So far 30,000 gift ideas have been added to the wishlist (and counting).</p>



<h2 class="wp-block-heading"><strong>The next feature request</strong></h2>



<p>With an app that sees 60,000 new users per month, I receive a lot of feature requests. Most recently, I received a one star review on the app store because my app isn&#8217;t accessible to the Visually Impared. When VoiceOver is activated, all it says is “button”, “button”, “button”, with no explanation.</p>



<p>Adding voice-over capabilities in Xojo is simple. The <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileuicontrol.html#mobileuicontrol">MobileUIControl</a> class has two String properties, AccessibilityHint and AccessibilityLabel.</p>



<p>But it actually is a lengthy task to check each control on each screen and make sure that the translations are correct.</p>



<p>VoiceOver support will soon be released in English and French, but all other localizations will be only ready next year. It is currently a bad time to get 30 different translators to work on the project under such short notice.</p>



<p>Xojo has enabled me to create a business out of developing iOS apps for the App Store. Including all of my apps, I have had over 6.5 million downloads and counting. Secret Santa is a prime example of what is possible and how you can leverage your Xojo skills to expand to other platforms when you need to. I look forward to what’s to come and will be at <a href="https://www.xojo.com/xdc">XDC London</a> to learn more about the future.</p>



<p>If you are organizing a Secret Santa event or just curious to see the app, download Secret Santa on the <a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8">App Store.</a></p>



<p><em>Jérémie Leroy has been using Xojo since 2008, he won two Xojo Design Awards in the iOS App category and has released over 13 iOS apps made with Xojo on the App Store. He also released </em><a href="https://github.com/jkleroy/iOSDesignExtensions"><em>iOSDesignExtensions</em></a><em> on Github to help style and polish your Xojo made iOS apps.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Super Simple Web Switch Control</title>
		<link>https://blog.xojo.com/2022/11/07/super-simple-web-switch-control/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Mon, 07 Nov 2022 21:20:21 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10952</guid>

					<description><![CDATA[Web Switch controls, you like them or you hate them. The functionality of a Switch control is so similar to a checkbox that we are going to actually "hack" one of them to make a super simple web switch control.]]></description>
										<content:encoded><![CDATA[
<p>Web Switch controls, you like them or you hate them. The functionality of a Switch control is so similar to a checkbox that we are going to actually &#8220;hack&#8221; one of them to make a super simple web switch control.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="599" src="https://blog.xojo.com/wp-content/uploads/2022/11/web-switch-control-1024x599.png" alt="" class="wp-image-10953" srcset="https://blog.xojo.com/wp-content/uploads/2022/11/web-switch-control-1024x599.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/11/web-switch-control-300x175.png 300w, https://blog.xojo.com/wp-content/uploads/2022/11/web-switch-control-768x449.png 768w, https://blog.xojo.com/wp-content/uploads/2022/11/web-switch-control.png 1314w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Place a WebCheckbox into your WebPage. Add the Opening Event Handler to your checkbox.</p>



<p>Inside, paste this code:</p>



<pre class="wp-block-code"><code>Me.ExecuteJavaScript("document.getElementById('" + Me.ControlID + "').classList.add('custom-switch');")
Me.Style.Value("padding-left") = "32px" // Adjust if needed</code></pre>



<p>Run the project. Enjoy!</p>



<p>If you like this control, consider creating a WebCheckbox subclass so you can easily reuse it.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WebUIControl Badges Using Extension Methods</title>
		<link>https://blog.xojo.com/2022/11/03/webuicontrol-badges-using-extension-methods/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Thu, 03 Nov 2022 17:59:19 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Extension Methods]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10934</guid>

					<description><![CDATA[I was having some fun with badges, trying to recreate a design. I’ve ended up writing a few extension methods to use them on almost any WebUIControl. ]]></description>
										<content:encoded><![CDATA[
<p>I was having some fun with badges, trying to recreate a design. I’ve ended up writing a few extension methods to use them on almost any WebUIControl. </p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="429" src="https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-1024x429.png" alt="" class="wp-image-10936" srcset="https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-1024x429.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-300x126.png 300w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-768x321.png 768w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-1536x643.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.12-AM-2048x857.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">But first, what’s an Extension Method anyway? </h3>



<p>There are situations where you want to add functionality to a Xojo Framework class. Let’s say we want to add a method to every visual web control. We know that every visual control inherits from WebUIControl. This class can’t be modified, as it’s part of the framework. One option would be subclassing each control and adding new methods… but that’s so boring… </p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="577" src="https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.21-AM-1024x577.png" alt="" class="wp-image-10937" srcset="https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.21-AM-1024x577.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.21-AM-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.21-AM-768x433.png 768w, https://blog.xojo.com/wp-content/uploads/2022/11/Screen-Shot-2022-11-03-at-9.24.21-AM.png 1342w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><a href="https://documentation.xojo.com/getting_started/using_the_xojo_language/modules.html#extension-methods">Extension Methods</a> are part of the Modules feature, allowing us to extend classes with methods, even if we don’t have access to their source code.</p>



<h3 class="wp-block-heading">Adding SetBadge and RemoveBadge methods to every visual control</h3>



<p>The first thing you need is a Module. Press on the Add button from the toolbar and select Module. The name of the module is up to you, I’ll be using WebExtensions in this example.</p>



<p>Now add a new method into that module, called &#8220;SetBadge&#8221;. Then, in the inspector, ensure its visibility is set to Global, instead of Public or Protected.</p>



<p>The magic happens in the first parameter of this method. “Extends” is the reserved keyword for this feature, for example:</p>



<pre class="wp-block-preformatted">Extends myInstance As ExampleClass</pre>



<p>Above method would be extending an imaginary class called “ExampleClass”, and its instance would be available inside that method, accessible from the variable “myInstance”.</p>



<p>In our case, for SetBadge, we want to use this method signature instead:</p>



<pre class="wp-block-preformatted">Extends control As WebUIControl, caption As String, indicator As String = "danger", top As Integer = -10, right As Integer = -10</pre>



<p>Inside, paste the method contents:</p>



<pre class="wp-block-preformatted">Var classes() As String = Array("xojo-badge", "d-flex", "p-2", _ 
"border", "border-light", "bg-" + indicator) 
classes.Add(If(caption.Length &lt; 2, "rounded-circle", "rounded-pill"))

Var styles() As String = Array("height: 21px", "font-size: 10px", _ 
"align-items: center", "color: white", "position: absolute", _ 
"top: " + top.ToString + "px", "right: " + Right.ToString + "px", _ 
"z-index: 10")

If caption = "" Or caption = " " Then caption = "&amp;nbsp;"
Var html As String = "&lt;span class=""" + String.FromArray(classes) + _
""" style=""" + String.FromArray(styles, ";") + """&gt;" + caption + "&lt;/span&gt;"

Var js() As String
js.Add("$('#" + control.ControlID + " .xojo-badge').remove();") 
js.Add("$('#" + control.ControlID + "').append(`" + html + "`);")
control.ExecuteJavaScript(String.FromArray(js))</pre>



<p>What this little sorcery does is appending a new HTML layer into our control, using some Bootstrap’s component CSS classes. Did you notice we are using &#8220;control&#8221; instead of &#8220;Self&#8221;? It matches the “control” variable from the method definition.</p>



<p>Add another Extension Method for removing the badges, called “RemoveBadge”.</p>



<p>The method definition reads like this:</p>



<pre class="wp-block-preformatted">Extends control As WebUIControl</pre>



<p>The content is a bit easier this time:</p>



<pre class="wp-block-preformatted">Var js As String = "$('#" + control.ControlID + " .xojo-badge').remove();"
control.ExecuteJavaScript(js)</pre>



<p>That’s it. Plumbing done.</p>



<p>Now, if you have a WebButton called&#8230; &#8220;AwesomeButton&#8221;, you can set its badge using this code:</p>



<pre class="wp-block-preformatted">AwesomeButton.SetBadge("Hello!")</pre>



<p>And to remove it:</p>



<pre class="wp-block-preformatted">AwesomeButton.RemoveBadge()</pre>



<p>You can use these badges in different scenarios. From displaying a pending notifications counter in a WebButton, to validation errors in a WebTextField.</p>



<p>Adjust and play with the code to meet your needs!&nbsp;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>You can download the example from the <a href="https://github.com/piradoiv/xojo-web-badges">GitHub code repository</a>.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFDocument: New Annotations Types</title>
		<link>https://blog.xojo.com/2022/07/25/pdfdocument-new-annotations-types/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 25 Jul 2022 13:53:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[2022r2]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10488</guid>

					<description><![CDATA[The annotations feature on PDFDocument has been significantly extended in the release of Xojo 2022r2. Continue reading to learn about the new annotation types. Currently,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The annotations feature on PDFDocument has been significantly extended in the release of Xojo 2022r2. Continue reading to learn about the new annotation types.</p>



<p>Currently, Xojo&#8217;s PDFDocument supports the most common type of annotations for PDF &#8211; you know those little yellow boxes displayed like sticky notes on the pages of the PDF document that display their contents when clicked on.</p>



<p>Now with Xojo 2022r2 and later you have more options! And while most of these don&#8217;t look like &#8220;real&#8221; annotations or like something made using the Graphics methods, they will behave as the annotations you are familiar with using in PDF. What I mean by this is that they will display the associated text for the annotation while also allowing the user to Accept/Decline the annotation or interact with them by adding, for example, new replies.</p>



<p>Before reviewing the new options, let me just remind you: The PDF Standard dictates how some features must be implemented for a PDF. After that, it is up to the developers of the PDF viewer app to decide what features are implemented, keep in mind results can vary depending on the PDF viewer you or your user chose to use. As other many things related with PDF files, don&#8217;t expect every PDF viewer apps out there to support or adhere to the annotations outside of the most basic ones.</p>



<p>Adobe is the original creator of the PDF specification and its free PDF viewer, <a href="https://www.adobe.com/acrobat/pdf-reader.html">Acrobat Reader</a> app does support everything Xojo&#8217;s PDFDocument offers.</p>



<h3 class="wp-block-heading">Attaching Files to the PDF</h3>



<p>You&#8217;ll be able to embed any kind of file (except for those based in a Bundle structure) into the PDF document itself, for example an Excel file, a Hi-Res image, etc. Then the user viewing the PDF document will be able to open the attached file clicking in the annotation using whichever PDF Viewer app their computer/device has installed for the attached file format. Because this is an annotation, the user will be able to also edit the annotation or add new replies to it.</p>



<p>This is an example about how to create these kind of annotations:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Attached File Annotation: double click on me!"

g.FontSize = 20
g.DrawText(kContentText, 40, 60)

If exampleFile &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedFile(exampleFile, 40, 60, g.TextWidth(kContentText), 20)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFAttachedFile.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Here <code>exampleFile</code> is a FolderItem property that has been added to the project and that&#8217;s pointing to the file to embed.</p>



<p>And this is how it looks like in the resulting PDF file:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="439" src="https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1024x439.png" alt="" class="wp-image-10490" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1024x439.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-300x129.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-768x329.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1536x658.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-2048x878.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Callout Annotations</h3>



<p>These kind of annotations are perfect for pointing our or calling attention to any other item in the PDF page. They are highly customizable- you can decide for example a solid or dashed line, the termination of the line, the color and, of course the text to be displayed in the annotation itself.</p>



<p>This is an example showing how to add a Callout annotation to a PDFDocument:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Callout Annotation in PDF"

g.FontSize = 40
g.Bold = True
g.DrawText(kContentText, 40, 60)

g.Bold = False
g.FontSize = 12
g.DrawText(kSampleText, 40, 100, 200)

Var originY As Double = (g.TextHeight(kSampleText, 200) / 2)

Var tCallout As New PDFCallout("Callout Example", New Point(250, originY), New Point(300, originY + 50), _
 New Point(350, originY + 50), 100, 50)

tCallout.BorderStyle = PDFAnnotation.BorderStyles.Dashed
tCallout.DashPattern = Array(2.0, 2.0)
tCallout.DrawingColor = Color.Orange
tCallout.LineEndingStyle = PDFAnnotation.LineEndingStyles.OpenArrow
tCallout.Text = "Some sample text in the annotation"
tCallout.FontSize = 9.5

d.AddCallout(tCallout)

// Saving the created PDF document to the selected path.
Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFCalloutExample.pdf")

If f &lt;&gt; Nil Then
  
  d.Save(f)
  
End If
</code></pre>



<p>Where <code>kSampleText</code> is a Constant added to the project containing some sample text to be put in the page of the PDF.</p>



<p>And this is how the Callout will look like when opening the resulting PDF file in the viewer app:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="599" src="https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1024x599.png" alt="" class="wp-image-10491" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1024x599.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-300x176.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-768x450.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1536x899.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-2048x1199.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Line Annotations</h3>



<p>A &#8220;Line&#8221; annotation displays a straight line on the page with a text caption inside the line or above it.</p>



<p>It is also possible to add leader lines to both sides of the main line (with possitive or negative values) plus set other properties as the type of the line (solid, dashed, etc), the kind of termination used on both ends of the main line (i.e: open/close arrow, butt, circle, diamond, square…), the drawing color, line width or font size.</p>



<p>This is how a Line annotation looks like when the resulting PDFDocument is viewed using Acrobat Reader (in this case, using Leader lines):</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="605" src="https://blog.xojo.com/wp-content/uploads/2022/06/Line-1024x605.png" alt="" class="wp-image-10493" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/Line-1024x605.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-300x177.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-768x454.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-1536x907.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-2048x1210.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Video Annotations</h3>



<p>Yes, you can embed .mp4 files in the PDF created with PDFDocument, and these will be played from the PDF itself. This will increase the size of the generated PDF file because it will add the size of the embedded mp4 file itself! So it is good practice to optimize the video files as much as possible and use the video resolution you want them to be played and not a higher one.</p>



<p>You can also add this kind of content as an Attached File annotation too. In both cases the data of the file will be embedded in the generated PDF file. The main difference in this case is that the mp4 file will be opened using an external app and that you&#8217;ll be able to include other video file format besides .mp4.</p>



<p>The way to add this kind of annotation to a PDFDocument instance is quite simple, for example:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Embedded Video Annotation"

g.FontSize = 30
g.DrawText(kContentText, 40, 60)

If exampleVideo &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedMovie(exampleVideo, 40, 100, 478, 360)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFEmbeddedVideo.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Where <code>exampleVideo</code> is a FolderItem Property that has been added to the project. This is how a video annotation will look like when opening the resulting PDF in Acrobat Reader:</p>



<figure class="wp-block-image is-style-default"><img loading="lazy" decoding="async" width="918" height="600" src="https://blog.xojo.com/wp-content/uploads/2022/06/VideoAnnotation.gif" alt="" class="wp-image-10494"/></figure>



<h3 class="wp-block-heading">Sound Annotations</h3>



<p>In addition to video annotations, it is also possible to add sound files that can be played from the PDF itself. In this case, the audio files need to be in AIFF format with 2 audio channels (stereo), 16 bits of resolution and a sampling frequency of 44,1 kHz.</p>



<p>As it is the case with video annotations, you can opt to add this kind of content as an Attached File annotation, so it will be opened with an external app and opens the range of sound file formats you can embed into the PDF.</p>



<p>The way to add Sound annotations using PDFDocument is shown here:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
g.FontSize = 30

Const kContentText As String = "Embedded Sound Annotation"

Var x, y, width, height As Double

x = g.Width/2 - width/2
y = 60

width = g.TextWidth(kContentText)
height = g.TextHeight

g.DrawText(kContentText, x, y)

If exampleSound &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedSound(exampleSound,x,y,width,height)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFEmbeddedSound.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Here <code>exampleSound</code> is a FolderItem Property added to the project. And this is how a Sound annotation will look when the PDF document is opened using Acrobat Reader:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="361" src="https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1024x361.png" alt="" class="wp-image-10495" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1024x361.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-300x106.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-768x271.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1536x542.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-2048x722.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Markup Annotations</h3>



<p>A Markup annotation is intended to mark an underlying text content using any of the different available types, for example &#8220;Highlight&#8221;, &#8220;Squiggly&#8221; (usually used to mark a text that needs some kind of correction), &#8220;Underline&#8221; or &#8220;Strikeout&#8221;. Besides the Markup type, it is also possible to set the color of the annotation.</p>



<p>For example, the following snippet of code adds two Markup annotations to the page of the PDFDocument using the Highlight and Squiggly types:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Markup Annotation in PDF"

g.FontSize = 40
g.Bold = True
g.DrawText(kContentText, 40, 60)

// Adding a Markup annotation with the Highlight type (Default)
d.AddMarkup(40,40,g.TextWidth(kContentText),g.FontSize,"Let's focus on this Section")

g.Bold = False
g.FontSize = 12
g.DrawText(kSampleText, 40, 100, g.Width-80)

// Adding a Markup annotation with the Squiggly type
d.AddMarkup(40,195,210,g.FontSize,"Some text to correct!",Color.Red,PDFAnnotation.MarkupTypes.Squiggly)

// Saving the created PDF document to the selected path.
Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFMarkupExample.pdf")

If f &lt;&gt; Nil Then
  
  d.Save(f)
  
End If</code></pre>



<p>And this is how it looks when the resulting document is opened in Adobe Acrobat Reader:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="632" src="https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1024x632.png" alt="" class="wp-image-10499" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1024x632.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-768x474.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1536x949.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-2048x1265.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Bonus</h3>



<p>Let me end with one other minor improvement to PDFDocument annotations: starting with Xojo 2022r2 all of them include metadata information about the creation and modification date and time. this information will be displayed as part of the annotation metadata when the item is selected in the viewer app.</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>PDFDocument: How to Add New Content to a Given Page</title>
		<link>https://blog.xojo.com/2022/06/02/pdfdocument-how-to-add-new-content-to-a-given-page/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 02 Jun 2022 13:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10413</guid>

					<description><![CDATA[When we create a PDF document is impossible (in most of the cases) to anticipate how many pages it will have. And yet, that is something that we are going to need if, for example, we want to add a footer reflecting the current page number over the total of pages in the document. The solution is using the PageCount and CurrentPage properties in the PDFDocument class. ]]></description>
										<content:encoded><![CDATA[
<p>When creating a PDF it is not always possible to anticipate how many pages the document will have. And yet, that is necessary, for example, to add a footer reflecting the current page number over the total of pages in the document. So how do you add this new content to your PDFs?</p>



<p>The solution is to use the <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument-pagecount"><code>PageCount</code></a> and <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument-currentpage"><code>CurrentPage</code></a> properties in Xojo&#8217;s <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument"><code>PDFDocument</code></a> class. The PageCount property gives the total number of pages in the PDF, and the the CurrentPage property (read/write) can be used to reach a given page within a PDF being created. This way, when we assign a new value to the CurrentPage property, it will retrieve the current <a href="https://documentation.xojo.com/api/graphics/graphics.html#graphics">Graphics</a> context for that page in order to continue adding new content.</p>



<p>Let&#8217;s see how this works through this example. Let&#8217;s create a 10 page PDF and then add the numbered footer on every page of the document:</p>



<pre class="wp-block-preformatted">Var d As New PDFDocument
Var g As Graphics = d.Graphics

// Adding a total of 10 pages to the PDF
For n As Integer = 1 To 9
  g.DrawText("Some sample text in page #" + n.ToString, 20, 20)
  g.NextPage
Next n

// Once we create the pages with some content on them,
// we iterate on every page in order to add the footer.
// Remember that the first page in a PDF document starts at 1!
Var x As Integer = d.PageCount
For i As Integer = 1 To x

// Here is where we set which will be the current "active" page;
// that is, the one retrieving the current Graphics context.
d.CurrentPage = i
g.DrawText("Page " + i.ToString + " of " + x.ToString, 20, g.Height - 30)
Next i

// Lastly, we save our PDF to a FolderItem.
d.Save(SpecialFolder.Desktop.Child("CurrentPage.PDF"))</pre>



<p>Run this sample snippet of code and you&#8217;ll get a PDF on your computer Desktop. Open it using your preferred PDF viewer app and you&#8217;ll see how the second loop was able to draw again on every one of the pages from the PDF we created.</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>How To Download and Preview PDFs in Xojo Web Apps</title>
		<link>https://blog.xojo.com/2022/05/31/how-to-download-and-preview-pdfs-in-xojo-web-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 31 May 2022 18:10:19 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10417</guid>

					<description><![CDATA[Web Apps
How to download and preview PDFs in Xojo Web apps may be one of the most asked questions involving PDFDocument (font handling is a close second) I get. If you are interested in finding the best, and simplest, way to do this, continue reading.]]></description>
										<content:encoded><![CDATA[
<p>How to download and preview PDFs in Xojo Web apps may be one of the most asked questions involving <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument">PDFDocument</a> (<a href="https://blog.xojo.com/2022/04/05/pdfdocument-font-handling-improvements/">font handling</a> is a close second) I get. If you are interested in finding the best, and simplest, way to do this, continue reading.</p>



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


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="917" src="https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-1024x917.png" alt="" class="wp-image-10418" srcset="https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-1024x917.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-300x269.png 300w, https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-768x688.png 768w, https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-1536x1375.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/05/Captura-de-Pantalla-2022-05-18-a-las-12.53.12-2048x1833.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>To start, create a Web project, select <a href="https://documentation.xojo.com/api/user_interface/web/webpage.html#webpage">WebPage1</a> in the Navigator and drop a <a href="https://documentation.xojo.com/api/user_interface/web/webbutton.html#webbutton">WebButton</a> from the Library onto the upper-center of the page in the Layout Editor. In the associated Inspector Panel for the button change the following property:</p>



<ul class="wp-block-list"><li><strong>Caption:</strong> Create PDF</li></ul>



<p>Next, add the <code>Pressed</code> Event Handler to it and type the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">// Nothing really interesting here
// Create a new PDFDocument instance
// and assign its Graphic context to
// a variable
Var d As New PDFDocument
Var g As Graphics = d.Graphics

// The content of the PDF
// not that much, but it works for the
// main topic we are interested in
g.DrawText("Really simple PDF content", 20, 20)

// Here is where the **important** thing starts
// Creating a new WebFile instance and assigning it
// to the wf property added to the WebPage1 page
wf = New WebFile

// This is the thing: the PDFDocument.ToData method
// returns as a MemoryBlock (Direct conversion to String)
// the inner contents of the PDF document at this point
// so assign that to the "data" property of the
// WebFile instance
wf.Data = d.ToData

// It's important to set the right MIMEType for the file
// in this case, it's a PDF file
wf.MIMEType = "application/pdf"

// We assign the file name…
wf.Filename = "SamplePDF.pdf"

// …and set the ForceDownload to true…
wf.ForceDownload = True

// …so the file is, in effect, downloaded when calling
// the Download method on our WebFile instance
Call wf.Download

// Because we want to display the PDF file in an HTMLViewer
// set the ForceDownload property back to False
wf.ForceDownload = False

// And, finally, preview the PDF Document loading it in the
// HTMLviewer added to the WebPage1 page
HTMLViewer1.LoadURL(wf.URL)
</pre>



<p>As you can see here, this simple fragment of code is in charge of creating a sample PDF document, downloading it and also previewing it in an <a href="https://documentation.xojo.com/api/user_interface/web/webhtmlviewer.html#webhtmlviewer">HTMLViewer</a> instance. Now, add an HTMLViewer control to the WebPage1 page.</p>



<p>Select the WebPage1 item in the Navigator again so it is visible in the Layout Editor. Next, drag the HTMLViewer control from the Library and drop it below the WebButton added in the previous step.</p>



<p>With the HTMLViewer1 control selected in the Layout Editor, click on the four lock icons under the Locking section from the associated Inspector Panel so they are closed.</p>



<p>Finally, add the expected <a href="https://documentation.xojo.com/api/web/webfile.html#webfile">WebFile</a> property to the WebPage1 page using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> wf</li><li><strong>Data Type:</strong> WebFile</li><li><strong>Scope:</strong> Private</li></ul>



<p>You&#8217;ll probably want to move this property to the <a href="https://documentation.xojo.com/api/web/websession.html#websession">Session</a> object in your Web projects so every connected user to the app can handle their own generated PDF documents.</p>



<p>And…&nbsp;that&#8217;s all! Run the project, click the button and see how it works.</p>



<p>Have fun!</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>Graphics: Right and Center Aligned Text</title>
		<link>https://blog.xojo.com/2022/05/17/graphics-right-and-center-aligned-text/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 17 May 2022 13:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10351</guid>

					<description><![CDATA[The DrawText method from the Graphics class offers a simple way to left-align text at the given X and Y coordinates, even applying a wrap value to wrap every line of the text block at the provided width value. Wouldn't it be great to be able to do the same thing while aligning blocks of text to the right and center? Continue reading and I will show you a technique you can use as the starting point which you can fine-tune to your specific needs.]]></description>
										<content:encoded><![CDATA[
<p>The <a href="https://documentation.xojo.com/api/graphics/graphics.html#graphics-drawtext">DrawText</a> method from the <a href="https://documentation.xojo.com/api/graphics/graphics.html#graphics">Graphics</a> class offers a simple way to left-align text at the given X and Y coordinates, even applying a wrap value to wrap every line of the text block at the provided width value. Wouldn&#8217;t it be great to be able to do the same thing while aligning blocks of text to the right and center? Continue reading and I will show you a technique you can use as the starting point which you can fine-tune to your specific needs.</p>



<div class="wp-block-image wp-image-10353 size-large is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="665" src="https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentLinux-1024x665.png" alt="" class="wp-image-10353" srcset="https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentLinux-1024x665.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentLinux-300x195.png 300w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentLinux-768x499.png 768w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentLinux.png 1472w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>Right-aligned and centered text on Linux Desktop, both in a Picture and a document created with PDFDocument.</figcaption></figure></div>



<h3 class="wp-block-heading">Graphics Extensions</h3>



<p>To start, and because we want to provide this ability to any graphic context, it makes sense to include all our logic in a Module. Let&#8217;s name it GraphicExtensions (as usual you can opt to use any other name). Start a new Xojo project and add a new Module to it using the following values in the Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> GraphicsExtensions</li></ul>



<p>Next, and with the GraphicsExtensions item selected in the Navigator, add a new method to it using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> DrawText</li><li><strong>Parameters:</strong> Extends g As Graphics, value As String, x As Double, y As Double, wrap As Double, alignment As TextAlignments = TextAlignments.Left</li><li><strong>Scope:</strong> Global</li></ul>



<p>As you can see, it nearly replicates the standard DrawText method from the Graphics class. Some things to note here, we are using the <a href="https://documentation.xojo.com/api/language/extends.html#extends">Extends</a> keyword in combination with the first parameter to instruct the compiler that this method will &#8220;extend&#8221; the existing functionality of the Graphics class, so you&#8217;ll be able to invoke it using the usual dot notation on any instance created from the Graphics class.</p>



<p>The second thing is the last of the parameters &#8220;alignment As TextAlignments&#8221; <a href="https://documentation.xojo.com/api/text/textalignments.html#textalignments">TextAlignments</a> is a global enumeration that we are going to use to learn the text alignment the user wants to apply to the block of text.</p>



<p>Next, type the following snippet of code in the associated Code Editor for the method:</p>



<pre class="wp-block-preformatted">#Pragma DisableBackgroundTasks
#Pragma DisableBoundsChecking
#Pragma NilObjectChecking False

value = value.ReplaceLineEndings(EndOfLine)

Select Case Alignment
  
Case TextAlignments.Default, TextAlignments.Left
  
  g.DrawText(value, x, y + g.TextHeight, wrap - x)
  
Case TextAlignments.Center, TextAlignments.Right
  
  Var tOutput() As String = PrepareOutput(g, value, wrap, x)
  
  Var tx, ty As Double
  ty = y + g.TextHeight
  
  Select Case Alignment
    
  Case TextAlignments.Center
    
    For Each s As String In tOutput
      
      tx = If(Wrap = 0, ((g.Width - Wrap) / 2 - g.TextWidth(s) / 2) + (x / 2), (wrap / 2 - g.TextWidth(s) / 2) + (x / 2))
      g.DrawText(s, tx, ty)
      ty = ty + g.TextHeight
      
      If ty &gt; g.Height Then Exit
      
    Next
    
  Case TextAlignments.Right
    
    For Each s As String In tOutput
      
      tx = If(Wrap = 0, (g.Width - g.TextWidth(s)) + x / 2, (wrap - x) - g.TextWidth(s) + x)
      g.DrawText(s, tx, ty)
      ty = ty + g.TextHeight
      
      If ty &gt; g.Height Then Exit
      
    Next
    
  End Select
  
End Select
</pre>



<p>As you can see, this code looks into the value of the Alignment parameter to see the approach to apply. If the Alignment equals to Default or Left we simply call the standard DrawText method on the received graphics context represented by the &#8220;g&#8221; variable. If not, we need to do some stuff to the received block of text to create the required chunks (or lines) that do fit the available width plus the received wrapping value. This is done in the PrepareOutput method.</p>



<p>Once we have all the lines with the apropiate widths in the Output array, then we only need to do some basic maths in order to calculate the final TX coordinate for every line, incrementing the TY coordinate on every new line to draw. As you can see, and in order to speed-up things a bit more, we check if the calculated TY coordinate is beyond the visible area of the graphic context and, if it is the case, we exit the function (it wouldn&#8217;t make much sense drawing text that is not going to be visible and whose processing consumes time).</p>



<p>Of course, the calculation of the TX and TY coordinates depends on the value of the Alignment parameter; that is, if the block of text is going to be drawn right aligned or centered.</p>



<h3 class="wp-block-heading">Calculating Every Line Width</h3>



<p>Now add the PreapareOutput method to the GraphicsExtensions module using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> PrepareOutput</li><li><strong>Parameters:</strong> g As Graphics, value As string, wrap As Double, x As Double</li><li><strong>Return Type:</strong> String()</li><li><strong>Scope:</strong> Private</li></ul>



<p>And typing the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">#Pragma DisableBoundsChecking
#Pragma DisableBackgroundTasks
#Pragma NilObjectChecking False

Var totalWidth As Double = If(wrap = 0, g.Width - x, wrap - x)

Var Input() As String = value.ToArray(EndOfLine)
Var output() As String

For Each s As String In Input
  
  If g.TextWidth(s) &lt;= totalWidth Then
    output.Add(s)
  Else
    AdjustWidth(g, s, totalWidth, output)
  End If
  
Next

Return output
</pre>



<p>Once again, the first lines are some pragmas put in place to speed-up things, then the totalWidth variable will store the required maximum width value for every line. The Input array is going to store every paragraph from the source text, while the Output array will store every processed line and, the one returned to the method calling PrepareOutput.</p>



<p>Then we need to iterate every entry in the Input array and check if its width meets the totalWidth requirement. If it does, then that entry will be added to the Output array; if not, we still need to split the &#8220;paragraph&#8221; into as many chunks of text as needed that meet the expected maximum width. That is something that&#8217;s going to be done by the AdjustWidth method.</p>



<h3 class="wp-block-heading">Splitting Chunks of Text …&nbsp;Recursively</h3>



<p>Add the third, and last required, method to the GraphicExtensions module using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> AdjustWidth</li><li><strong>Parameters:</strong> g As Graphics, s As String, width As Double, ByRef output() As String</li><li><strong>Scope:</strong> Private</li></ul>



<p>Next, type the following lines of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">#Pragma DisableBoundsChecking
#Pragma DisableBackgroundTasks
#Pragma NilObjectChecking False

Var n As Integer

If g.TextWidth(s) &lt;= width Then
  output.Add(s)
Else
  
  // This can be improved pre-calculating the initial value for "n"…&nbsp;so it's
  // left as an exercise for the reader :-)
  
  While round(g.TextWidth(s.Left(s.Length - n))) &gt; width
    n = n + 1
  Wend
  
  output.Add(s.Left(s.Length - n))
  
  AdjustWidth(g, s.Right(n), width, output)
  
End If
</pre>



<p>As you can see, if the width of the received string is less than or equal to the expected width, then it is added to the Output array. If not, we are using a really less than optimal technique to calculate the appropriate one, saving the resulting string to the Output array and passing the remaining of the string again to the method. You&#8217;ll probably want to change some things here to better pre-calculate the initial value of the <code>n</code> variable.</p>



<h3 class="wp-block-heading">Testing It</h3>



<p>We have everything in place, so let&#8217;s test it! Start by adding a new constant to the Window1 window and name it <code>kSampleText</code>. Use the associated Inspector Panel to assign the block of text you want to use for testing (personally I like to use the <a href="https://www.lipsum.com">https://www.lipsum.com</a> website for getting sample text).</p>



<p>If you prefer, you can <a href="https://www.dropbox.com/s/amt86u9fnbq31xh/GraphicsExtensions.xojo_binary_project.zip?dl=1">download the complete Example project from this link</a>.</p>



<p>Add next the Opening Event Handler to the Window1 window and type following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Var p As New Picture(612, 792)
Var d As New PDFDocument

Var g As Graphics = p.Graphics
g.FontName = "Helvetica"
Var gPDF As Graphics = d.Graphics

g.DrawText(kSampleText, 40, 10, 570, TextAlignments.Right)
gPDF.DrawText(kSampleText, 40, 10, 570, TextAlignments.Right)

Var tH As Double = g.TextHeight(kSampleText, 570) + g.TextHeight * 4
Var tPH As Double = gPDF.TextHeight(kSampleText, 570) + gPDF.TextHeight * 4

g.DrawText(kSampleText, 40, th, 570, TextAlignments.Center)
gPDF.DrawText(kSampleText, 40, tPh, 570, TextAlignments.Center)

CustomDesktopCanvas1.Image = p
d.Save(SpecialFolder.Desktop.Child("PDFTextAlignment.pdf"))
</pre>



<p>As you can see, I chose the &#8220;Helvetica&#8221; font, but you can change it to any font that is available in your OS. The point here is that we are feeding our &#8220;extended&#8221; DrawText method with the sample text and the alignment we want to use in for drawing it both in the graphic context of a Picture and the one from a PDFDocument instance. Also, CustomDesktopCanvas1 is a simple Canvas subclass with an &#8220;image&#8221; property added to it as a computed property, so when a new value is assigned it will refresh itself and the Paint event will draw the picture centered in the canvas.</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="838" src="https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-1024x838.png" alt="" class="wp-image-10352" srcset="https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-1024x838.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-300x245.png 300w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-768x628.png 768w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-1536x1257.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/05/AlignmentMacOS-2048x1675.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>Run the example project and you should see something similar to the result displayed in the screenshots. Of course, there are still some details to take care of, for example when a line is split so the last letter goes over to the next line and things like that but, as mentioned in the beginning of this post, this is just a starting point. Adapt and improve upon it as needed.</p>



<p>Have fun!</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>XojoTalk 038 &#8211; Ask the Engineers Panel Q&#038;A from XDC Anywhere</title>
		<link>https://blog.xojo.com/2022/05/02/xojotalk-038-ask-the-engineers-panel-qa-from-xdc-anywhere/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 02 May 2022 16:48:51 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[XojoTalk]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10331</guid>

					<description><![CDATA[As part of XDC Anywhere, the Xojo Engineering team takes your questions.]]></description>
										<content:encoded><![CDATA[
<p>As part of XDC Anywhere, the Xojo Engineering team takes your questions.</p>



<p>Download <a href="https://files.xojo.com/Podcasts/XojoTalk-038.mp3">mp3</a> or watch on Xojo&#8217;s <a href="https://youtu.be/FK9pRCa0li0">YouTube Channel</a>.</p>



<p>Topics include:</p>



<ul class="wp-block-list"><li><a href="https://xojo.com/company/team.php">Xojo Team</a></li><li><a href="https://documentation.xojo.com/index.html">New Xojo Documentation</a></li><li><a href="https://documentation.xojo.com/resources/release_notes/2022r1.html">Xojo 2022 Release 1 Release Notes</a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://files.xojo.com/Podcasts/XojoTalk-038.mp3" length="38096062" type="audio/mpeg" />

			</item>
		<item>
		<title>ImageViewer: Loading Images from a URL in Desktop and iOS Apps</title>
		<link>https://blog.xojo.com/2022/04/18/imageviewer-loading-images-from-a-url-in-desktop-and-ios-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 18 Apr 2022 16:05:36 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10292</guid>

					<description><![CDATA[The WebImageViewer control allow us to load and display any image retrieved from a given URL. Wouldn't be nice to have that same kind of functionality in the Desktop and iOS versions of the ImageViewer? Continue reading and I'll show you how to achieve just that.]]></description>
										<content:encoded><![CDATA[
<p>The <a href="https://documentation.xojo.com/api/user_interface/web/webimageviewer.html#webimageviewer">WebImageViewer</a> control allows you to load and display any image retrieved from a given URL. Wouldn&#8217;t it be nice to have that same kind of functionality in the Desktop and iOS versions of the ImageViewer? Continue reading and I&#8217;ll show you how to achieve just that.</p>



<p>Let&#8217;s start with the Desktop version. Once we&#8217;ve finished this bit, you&#8217;ll only need to repeat the same steps using the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileimageviewer.html#mobileimageviewer">MobileImageViewer</a> to doo the same in your iOS app- just copy and paste the events, methods and properties to your iOS project!</p>



<p>Begin with a new Desktop project in Xojo, add a new <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopimageviewer.html#desktopimageviewer">DesktopImageViewer</a> by dragging it from the Library and dropping it into the Navigator. This creates a subclass of the DesktopImageViewer.</p>



<p>With the new CustomDesktopImageViewer still selected in the Navigator, use the associated Inspector Panel to change its name to &#8220;URLDesktopImageViewer&#8221; (of course you can use any name you want).</p>



<h3 class="wp-block-heading">Adding Properties</h3>



<p>Because we want to load an image from an URL, let&#8217;s start by adding some properties to our subclass. These will be responsible for storing the URL and the underlying URLConnection instance needed to retrieve the image data from the URL.</p>



<p>Start with the URL property. With URLDesktopImageViewer selected in the Navigator, choose the option &#8220;Add To URLDesktopImageViewer &gt; Property&#8221; from the contextual menu. Once this is added, use the associated Inspector Panel to change the following fields:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> URL</li><li><strong>Type:</strong> String</li><li><strong>Scope:</strong> Public</li></ul>



<p>With that property still selected in the Navigator, choose the option &#8220;Convert to Computed Property&#8221;. This adds a couple of methods under the URL property: Get and Set.</p>



<p>Select the Set method. The code put in that method will be executed every time the user (or the code) assigns a new value to the property. Now, add the following lines of code to the associated code editor for the Set method:</p>



<pre class="wp-block-preformatted">mURL = value
LoadURL</pre>



<p>You&#8217;ll likely want to display that property in the Inspector Panel so that the user can type a URL for that property using the Inspector Panel when a new instance of the class is added to the Layout Editor. In order to do that, select the URLDesktopImageViewer subclass in the Navigator and choose the Inspector Behavior option from the contextual menu. That action will bring up the following dialog:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/04/URLProperties-1024x784.png" alt="" class="wp-image-10308" width="768" height="588" srcset="https://blog.xojo.com/wp-content/uploads/2022/04/URLProperties-1024x784.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/04/URLProperties-300x230.png 300w, https://blog.xojo.com/wp-content/uploads/2022/04/URLProperties-768x588.png 768w, https://blog.xojo.com/wp-content/uploads/2022/04/URLProperties.png 1212w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>
</div>


<p>You&#8217;ll find the URL property under the Behavior section. Make sure to select the checkbox associated with the property and confirm the change by clicking the &#8220;OK&#8221; button.</p>



<p>Finally, add a second property to the URLDesktopImageViewer subclass. With the new property selected in the Navigator, use the associated Inspector Panel to change the following fields:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> Connection</li><li><strong>Type:</strong> URLConnection</li><li><strong>Scope:</strong> Protected</li></ul>



<h3 class="wp-block-heading">Adding (and Defining) Events</h3>



<p>With the URLDesktopImageViewer still selected in the Navigator, choose the &#8220;Add to URLDesktopImageViewer &gt; Event Handler…&#8221; option from the contextual menu to open the &#8220;Add Event Handler&#8221; window.</p>



<p>Select the Opening and Closing events and click on the &#8220;OK&#8221; button to confirm and close the window. You&#8217;ll see these two events have been added under the subclass.</p>



<p>Select the Opening event handler in the Navigator under the subclass hierarchy (if you don&#8217;t see the event names, then click on the disclosure triangle associated with the &#8220;Event Handlers&#8221; entry). That action will bring up the associated Code<strong> </strong>Editor for the event.</p>



<p>Write these two lines of code:</p>



<pre class="wp-block-preformatted">LoadURL
RaiseEvent Opening</pre>



<p>And because our subclass is &#8220;consuming&#8221; the Opening Event Handler, we need to create a new Event Definition for it, so the consumers of the subclass can handle their own code in that same event. To do that, with the URLDesktopImageViewer still selected in the Navigator, choose the &#8220;Add To URLDesktopImageViewer &gt; Event Definition&#8221; option from the contextual menu.  Xojo&#8217;s IDE will now add a new entry under the Events Definitions section of the class. Select it and use the associated Inspector Panel to change the following value:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> Opening</li></ul>



<p>Now, select the Closing event handler for the URLDesktopImageViewer subclass in the Navigator and type the following lines of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">If connection &lt;&gt; Nil Then
    RemoveHandler connection.contentReceived, WeakAddressOf ContentReceived
End If

RaiseEvent Closing</pre>



<p>And because the subclass is consuming the Closing event handler, you&#8217;ll need to add a new Event Definition for it using the same event handler name (Closing).</p>



<h3 class="wp-block-heading">Adding Methods</h3>



<p>As you see, the code in the Set method for the URL property and the Opening Event Handler are calling the LoadURL method. So we need to add that! With the URLDesktopImageViewer selected in the Navigator, choose the &#8220;Add to URLDesktopImageViewer &gt; Method&#8221; option from the contextual menu using the following value in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> LoadURL</li></ul>



<p>And type the following lines of code in the associated Code Editor for the method:</p>



<pre class="wp-block-preformatted">If Me.mURL &lt;&gt; "" Then
    Try
      If connection &lt;&gt; Nil Then
        RemoveHandler connection.ContentReceived, WeakAddressOf ContentReceived
      End If

      connection = New URLConnection
      AddHandler connection.ContentReceived, WeakAddressOf ContentReceived
      connection.Send("GET", mURL)
    End Try
End If</pre>



<p>In short, this creates a new URLConnection instance and assigns it to the Connection property. In order to handle the events generated during the URLConnection instance execution, we need to attach its events to some methods in our code. We achieve this with the AddHandler function which provides the name of the name we want to handle, in this case ContentReceived and the address of the method that will do the work. This is done by passing the method name (ContentReceived) to the function WeakAddressOf (or AddressOf, for the case).</p>



<p>Then, we need only to call the Send method of the URLConnection class and provide the &#8220;GET&#8221; verb and the URL that holds the picture we want to retrieve.</p>



<p>The last step is adding the ContentReceived method that will substitute the functionality of the ContentReceived Event Handler for our URLConnection instance.</p>



<p>Add a new method to the URLDesktopImageViewer subclass using the following values in the associated Code Editor:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> ContentReceived</li><li><strong>Parameters:</strong> tCon As URLConnection, URL As String, HTTPStatus As Integer, content As String</li><li><strong>Scope:</strong> Public</li></ul>



<p>As you can see, when we create a method that will substitute the functionality of an Event Handler, we need to provide the same type and number of parameters used by the original Event Handler, plus a first parameter that will hold the instance itself. In this case it is the parameter <code>tCon As URLConnection</code>.</p>



<p>Now type the following lines of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Try

    If httpStatus = 200 Then Me.Image = Picture.FromData(content)

End Try</pre>



<p>If we receive the &#8220;OK&#8221; status from the connection instance, then we assign the Picture created from the received data to the Image property of the control. And because <em>things can go wrong</em><sup>TM</sup>, and we didn&#8217;t take care of all the possibilities in order to keep this tutorial short, that line of code is wrapped in a <code>Try…Catch</code> block.</p>



<h3 class="wp-block-heading">Testing URLDesktopImageViewer</h3>



<p>In order to test our subclassed control, select the Window1 item in the Navigator so the Layout Editor is open in the main area of the Xojo IDE. Then, drag the URLDesktopImageViewer item from the Navigator and drop it in the Window control displayed in the Layout Editor.</p>



<p>With the new control selected in the Layout Editor, use the Inspector panel to set its width and height values, and any other parameter you wish. The interesting thing here is that you&#8217;ll find the URL field under the Behavior section of the Inspector Panel; so go ahead and type any URL pointing to the image you want to retrieve (for example: https://www.xojo.com/assets/img/logo@2x.png)</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="646" height="568" src="https://blog.xojo.com/wp-content/uploads/2022/04/Assets.png" alt="" class="wp-image-10310" srcset="https://blog.xojo.com/wp-content/uploads/2022/04/Assets.png 646w, https://blog.xojo.com/wp-content/uploads/2022/04/Assets-300x264.png 300w" sizes="auto, (max-width: 646px) 100vw, 646px" /></figure>
</div>


<p>Done! Run the app and if your computer is connected to the Internet you&#8217;ll see how the image is retrieved from the given URL and displayed by the ImageViewer!</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="551" height="1024" src="https://blog.xojo.com/wp-content/uploads/2022/04/Captura-de-pantalla-2022-04-11-a-las-18.38.26-551x1024.png" alt="" class="wp-image-10295" srcset="https://blog.xojo.com/wp-content/uploads/2022/04/Captura-de-pantalla-2022-04-11-a-las-18.38.26-551x1024.png 551w, https://blog.xojo.com/wp-content/uploads/2022/04/Captura-de-pantalla-2022-04-11-a-las-18.38.26-161x300.png 161w, https://blog.xojo.com/wp-content/uploads/2022/04/Captura-de-pantalla-2022-04-11-a-las-18.38.26.png 738w" sizes="auto, (max-width: 551px) 100vw, 551px" /></figure>
</div>


<p>Of course, you can repeat these steps (or copy and paste them) in order to re-create your own URLiOSImageViewer control, as you can see in the above screenshot, with the Xojo iOS app running in the Simulator.</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>On-Device iOS Debugging in Xojo</title>
		<link>https://blog.xojo.com/2022/04/05/on-device-ios-debugging-in-xojo/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 05 Apr 2022 13:30:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10008</guid>

					<description><![CDATA[You may or may not be aware that running iOS projects in the Simulator does not allow you to check all of your app's features. There are a few features which rely on hardware capabilities which the Simulator cannot emulate. This can make it hard to track down bugs, and the only recourse is console logging. Starting in Xojo 2022r1 it's possible to run your apps right on a physical device connected by USB.]]></description>
										<content:encoded><![CDATA[
<p>You may or may not be aware that running <a href="https://documentation.xojo.com/topics/debugging/testing_and_debugging_your_ios_apps.html#running-your-app-in-the-ios-simulator">iOS projects in the Simulator </a>does not allow you to check all of your app&#8217;s features. There are a few features which rely on hardware capabilities which the Simulator cannot emulate. This can make it hard to track down bugs, and the only recourse is console logging. Starting in Xojo 2022r1 it&#8217;s possible to <a href="https://documentation.xojo.com/topics/debugging/testing_and_debugging_your_ios_apps.html#running-your-app-on-device">run your apps right on a physical device</a> connected by USB. Learn how in this post.</p>



<h2 class="wp-block-heading" id="setup">Setup</h2>



<p>Debugging on device requires your device be connected to your computer using a lightning cable.</p>



<p><strong>Computer</strong><br>You&#8217;ll need to launch Xcode, plug your phone in using USB and open Xcode&#8217;s Devices and Simulators window. In the navigation pane on the left, select the device and check the Show as run destination<strong> </strong>checkbox<strong>.</strong> </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="233" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1024x233.png" alt="" class="wp-image-10252" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1024x233.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-300x68.png 300w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-768x175.png 768w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1536x350.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-2048x466.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Device</strong><br>If you&#8217;ll be debugging over USB, go to the Settings app on your device, select Personal Hotspot and turn that on.</p>



<h3 class="wp-block-heading" id="apple-developer-portal">Apple Developer Portal</h3>



<p>For on-device debugging, your app profiles must be set up properly. For help on this, read <a href="https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/" data-type="URL" data-id="https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/">The Crazy Exercise That Is The Apple Signing Process</a>.</p>



<ol class="wp-block-list">
<li><strong>Certificates</strong>: You will need a Development certificate for yourself. Download it and double-click the file to install it.</li>



<li><strong>Identifiers</strong>: You will need an Application Identifier that matches the Bundle Identifier in your app.</li>



<li><strong>Devices</strong>: You must register all of the devices that you intend to debug on.</li>



<li><strong>Profiles</strong>: You will need to create a Development profile for the app and make sure it contains your Development certificate (from step 1) as well as each of the devices that you want to debug on (step 3). Download the profile and double-click the file to install it.</li>
</ol>



<h3 class="wp-block-heading" id="xojo">Xojo</h3>



<p>Debugging on-device requires that you set the Team from your account as well as setting the Build For property to App Store.</p>



<p>When you&#8217;re ready to run on a device, from the menu select Project &gt; Run On and select your device from the list. If everything is configured properly, your app should be transferred to the device and automatically run for you.</p>



<h2 class="wp-block-heading" id="notes">Notes</h2>



<p>The first time you debug an app, you will get a dialog on the device asking if your app can connect to the local network. You will need to allow that and then run your app from Xojo again.</p>



<p>Don&#8217;t allow your device to go to sleep while waiting for the app to build and transfer or the app won&#8217;t be able to launch. You can increase the amount of time on the device by going to Settings &gt; Display &amp; Brightness and selecting a new Auto-Lock timeout. The options are 2, 5, 10 or 15 Minutes or Never.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFDocument: Reports With Full Vectorial Quality</title>
		<link>https://blog.xojo.com/2022/04/05/pdfdocument-reports-with-full-vectorial-quality/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 05 Apr 2022 13:30:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Report Editor]]></category>
		<category><![CDATA[Reporting]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9948</guid>

					<description><![CDATA[Back in 2020 when PDFDocument was first introduced in Xojo, we had to make a compromise in order to render the output created via Xojo&#8217;s&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Back in 2020 when <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument">PDFDocument</a> was first introduced in Xojo, we had to make a compromise in order to render the output created via Xojo&#8217;s integrated <a href="https://documentation.xojo.com/topics/printing/the_report_editor/index.html#the-report-editor">Report Editor</a>. That was far from ideal, but we needed to first meet some other requirements in order to get the full vectorial quality you expect in both PDFs as well as in rendering reports.</p>



<p>With Xojo 2022r1 I am happy to say we have achieved that goal! The best part is that you don&#8217;t need to do anything to take advantage of the update. Keep your code as it is now and, the next time you output your report into a PDF document you&#8217;ll get the full vectorial quality you expect!</p>



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


<div class="wp-block-image wp-image-9949 size-large is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="355" src="https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-1024x355.png" alt="" class="wp-image-9949" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-1024x355.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-300x104.png 300w, https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-768x267.png 768w, https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-1536x533.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/02/PDFReports-2048x711.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption><strong>From left to right:</strong> PDF Report output using Xojo 2021r3.1, same report output using Xojo 2022r1, and an area of that PDF Zoomed at 400% in the Viewer app.</figcaption></figure>
</div>


<p>As you can see, the difference is quite notable. Additionally, because the new Reports rendering is full vectorial quality, that means that you will be able to select the text or even using the Search capability provided by your PDF viewer app.</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>TTC to TTF File Converter</title>
		<link>https://blog.xojo.com/2022/03/24/ttc-to-ttf-file-converter/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 24 Mar 2022 13:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Font]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10107</guid>

					<description><![CDATA[TTC files are TrueType Collection files that contain the data needed to represent multiple font styles and font weights; this is a collection. On the other hand, TTF files are TrueType Font files, that contains the data required to work with only one font style or one font weight (for example: Regular, Bold or Light).]]></description>
										<content:encoded><![CDATA[
<p>TTC files are TrueType Collection files that contain the data needed to represent multiple font styles and font weights; this is a collection. On the other hand, TTF files are TrueType Font files, that contains the data required to work with only one font style or one font weight (for example: Regular, Bold or Light).</p>



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



<p>There are a lot of free websites you can use to extract the individual styles and weights from a .ttc file and create .ttf files. But why not do this with Xojo, just for fun … or because I need it! Keep reading and I will show you how.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="1280" height="720" src="https://blog.xojo.com/wp-content/uploads/2022/03/37F1D04B-7415-48C6-89C0-F1B64A9BD775.gif" alt="" class="wp-image-10222"/></figure>



<p>Extracting the available styles and weights from TTC files requires parsing its data to find the data chunks required to compose the TTF. That is what we are going to do. Start by creating a new Desktop project (you can adapt it later for any supported Xojo targets like Web or Mobile).</p>



<h3 class="wp-block-heading">Building the TTC to TTF Converter</h3>



<p>All the work is going to be done via a method; but because it will be dealing with font files, it would be a good idea to start by creating our own <code>FontUtilities</code> module. So, add a new module to the project and name it &#8220;FontUtilities&#8221; in the Inspector Panel.</p>



<p>Next, with <code>FontUtilities</code> selected in the Navigator, add a new method to it using the following signature:</p>



<ul class="wp-block-list">
<li><strong>Method Name:</strong> ExtractTTFStylesFromTTC</li>



<li><strong>Parameters:</strong> inputFile As FolderItem, outputFolder As FolderItem</li>



<li><strong>Scope:</strong> Public</li>
</ul>



<p>And add the following code into the associated Code Editor:</p>



<pre class="wp-block-preformatted">#Pragma DisableBackgroundTasks
#Pragma DisableBoundsChecking
#Pragma StackOverflowChecking False

If inputFile = Nil Or Not inputFile.Exists Then Return
If outputFolder = Nil Or Not outputFolder.IsFolder Or Not outputFolder.IsWriteable Then Return

Var mb As MemoryBlock

Var rb As BinaryStream = BinaryStream.Open(inputFile)
mb = rb.Read(inputFile.Length)
mb.LittleEndian = False
rb.Close

If mb &lt;&gt; Nil Then
  
  Var OutputBuffers() As MemoryBlock
  
  // Let's make sure this is a .ttc file by checking the first four bytes of the header
  
  If mb.StringValue(0, 4) &lt;&gt; "ttcf" Then Return
  
  // offset for the total of faces/styles in the ttc file
  Var totalFaces As Integer = mb.UInt32Value(8)
  
  Var tableHeaderOffset As Integer
  Var tableCount As UInt16
  Var headerLength, tLength, tableLength, totalLength, currentOffset As Integer
  
  Var outputBuffer As MemoryBlock
  
  For n As Integer = 0 To totalFaces - 1
    
    // 0x0c is the first possition of the tableHeader offsets
    tableHeaderOffset = mb.UInt32Value(12 + (n * 4))
    
    // offset to the table count from the current table header offset
    tableCount = mb.UInt16Value(tableHeaderOffset+4) 
    
    headerLength = 12 + tableCount * 16
    
    tableLength = 0 
    
    For j As Integer = 0 To tableCount - 1
      
      tLength = mb.UInt32Value(tableHeaderOffset+12+12+(j*16))
      tableLength = tableLength + Bitwise.BitAnd(tLength + 3, Bitwise.OnesComplement(3)) // next value multiple of four
    Next
    
    totalLength = headerLength + tableLength
    
    outputBuffer = New MemoryBlock(totalLength)
    outputBuffer.LittleEndian = False
    
    //Copy table to the buffer for the new file
    outputBuffer.StringValue(0,headerLength - 1) = mb.StringValue(tableHeaderOffset, headerLength - 1)
    
    currentOffset = headerLength
    
    Var tOffset, tOtherLength As Integer
    
    For j As Integer = 0 To tableCount - 1
      tOffset = mb.UInt32Value(tableHeaderOffset + 12 + 8 + (j * 16))
      tOtherLength = mb.UInt32Value(tableHeaderOffset + 12 + 12 + (j * 16))
      outputBuffer.UInt32Value(12 + 8 + (j * 16)) = currentOffset
      
      // Copy data to the buffer for the new file
      outputBuffer.StringValue(currentOffset, tOtherLength - 1) = mb.StringValue(tOffset, tOtherLength - 1)
      
      outputBuffer.UInt32Value(currentOffset) = mb.UInt32Value(tOffset)
      currentOffset = currentOffset + Bitwise.BitAnd(tOtherLength + 3, Bitwise.OnesComplement(3)) // next value multiple of four
    Next
    outputBuffers.Add(outputBuffer)
  Next
  
  // Let's create the .ttf files in the output folder
  Var max As Integer = outputBuffers.Count - 1
  Var outputFile As FolderItem
  
  For n As Integer = 0 To max
    outputFile = outputFolder.Child(inputFile.Name.NthField(".", 1) + " " + n.ToString + ".ttf")
    Var ob As BinaryStream = BinaryStream.Create(outputFile)
    ob.Write(outputBuffers(n))
    ob.Close
  Next
End If</pre>



<h3 class="wp-block-heading">Testing the TTC to TTF Converter</h3>



<p>Now, let&#8217;s create a minimal user interface in order to test it. Select the <code>Window1</code> window in the Navigator in order to bring up the Layout Editor. Next, drag a <code>DesktopButton</code> from the Library and drop it inside the window area in the Layout Editor. Use the alignment guides to help you to leave enough room between the button and the window margins.</p>



<p>Double click the button in the Layout Editor to open the Add Event Handler dialog box. The <code>Pressed</code> Event Handler should be selected already, so simply confirm it clicking on the &#8220;OK&#8221; button.</p>



<p>The <code>Pressed</code> Event Handler has been added under <code>Button1</code> in the Navigator and with its associated Code Editor visible in the main area, type the following lines of code:</p>



<pre class="wp-block-preformatted">Var inputFontFile As FolderItem = FolderItem.ShowOpenFileDialog(".ttc")
Var outputFolder As FolderItem = FolderItem.ShowSelectFolderDialog

FontUtilities.ExtractTTFStylesFromTTC(inputFontFile, outputFolder)</pre>



<p>The first line of code will ask the user to select the &#8220;.ttc&#8221; font file to process, and the second line will ask for the destination folder where the output (the converted .ttf font files) will be stored. Finally, the third line of code is the one calling our <code>ExtractTFFStylesFromTTC</code> method passing along both the file to process and the output folder.</p>



<p>That&#8217;s all! Click on the Run button in the main toolbar of the Xojo IDE. Once the app is running, click on the button to select any &#8220;.ttc&#8221; file you want to process. Next, the app will ask you to select the output folder and you will be able to see the extracted files inside the selected output folder.</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>Building a Dark Mode Capable TabPanel on Windows</title>
		<link>https://blog.xojo.com/2022/03/01/building-a-dark-mode-capable-tabpanel/</link>
		
		<dc:creator><![CDATA[Wayne Golding]]></dc:creator>
		<pubDate>Tue, 01 Mar 2022 14:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9747</guid>

					<description><![CDATA[Xojo supports dark mode in most of the Desktop controls. However, the TabPanel control doesn’t yet support dark mode. But it can be made to support it. I use a segmented button and a PagePanel to overcome this and in the blog post, I’ll show you how. ]]></description>
										<content:encoded><![CDATA[
<p>Xojo supports dark mode in most of the Desktop controls. However, the <a href="https://documentation.xojo.com/api/user_interface/controls/tabpanel.html#tabpanel">TabPanel</a> control doesn’t yet support dark mode. But you can make an alternative that works with dark mode. I use a <a href="https://documentation.xojo.com/api/user_interface/controls/segmentedbutton.html#segmentedbutton">SegmentedButton</a> and a <a href="https://documentation.xojo.com/api/user_interface/controls/pagepanel.html#pagepanel">PagePanel</a> to overcome this and in the blog post, I’ll show you how. </p>



<p>Let’s get started by creating a new Desktop project. We’ll add two colour groups, one for the border which we’ll name Border, choosing Named and selecting Active Border from the menu.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="306" height="312" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-8.png" alt="" class="wp-image-10027" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-8.png 306w, https://blog.xojo.com/wp-content/uploads/2022/02/image-8-294x300.png 294w" sizes="auto, (max-width: 306px) 100vw, 306px" /></figure>



<p>The second is for the background which we’ll name Background, choosing Named and selecting Window.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="316" height="316" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-9.png" alt="" class="wp-image-10028" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-9.png 316w, https://blog.xojo.com/wp-content/uploads/2022/02/image-9-300x300.png 300w, https://blog.xojo.com/wp-content/uploads/2022/02/image-9-150x150.png 150w" sizes="auto, (max-width: 316px) 100vw, 316px" /></figure>



<p>Now add a ContainerControl to the project and call it myTabpanel.&nbsp;Set its background colour to background.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="484" height="172" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-10.png" alt="" class="wp-image-10029" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-10.png 484w, https://blog.xojo.com/wp-content/uploads/2022/02/image-10-300x107.png 300w" sizes="auto, (max-width: 484px) 100vw, 484px" /></figure>



<p>Next add a SegmentedButton to the top left corner of the container.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="472" height="476" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-11.png" alt="" class="wp-image-10030" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-11.png 472w, https://blog.xojo.com/wp-content/uploads/2022/02/image-11-297x300.png 297w, https://blog.xojo.com/wp-content/uploads/2022/02/image-11-150x150.png 150w" sizes="auto, (max-width: 472px) 100vw, 472px" /></figure>



<p>In the Inspector for the SegmentedButton edit the segments.</p>



<p>Set the first segment as selected.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="580" height="464" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-12.png" alt="" class="wp-image-10031" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-12.png 580w, https://blog.xojo.com/wp-content/uploads/2022/02/image-12-300x240.png 300w" sizes="auto, (max-width: 580px) 100vw, 580px" /></figure>



<p>Now add a rectangle and set its left position to 0 and its top position to 24 (the height of the segemented button) and drag the bottom right corner to fit the container.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="476" height="484" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-13.png" alt="" class="wp-image-10032" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-13.png 476w, https://blog.xojo.com/wp-content/uploads/2022/02/image-13-295x300.png 295w" sizes="auto, (max-width: 476px) 100vw, 476px" /></figure>



<p>Lock its bottom and right boundaries.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="394" height="240" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-14.png" alt="" class="wp-image-10033" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-14.png 394w, https://blog.xojo.com/wp-content/uploads/2022/02/image-14-300x183.png 300w" sizes="auto, (max-width: 394px) 100vw, 394px" /></figure>



<p>We’ll now set its border colour to border. This will provide the outline of the panel.</p>



<p>Now we’ll add a PagePanel to the project to fit just inside the rectangle. Set its Left position to 1 and its Top position to 25. Its Width and Height should be 2 less than the rectangle – let the Xojo IDE do this for you.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="214" height="44" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-15.png" alt="" class="wp-image-10034"/></figure>



<p> and  </p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="200" height="44" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-16.png" alt="" class="wp-image-10035"/></figure>



<p>on moving away from the field the IDE will replace the entry with the result. Again, we’ll set the border locks for bottom and right.</p>



<p>Next, we’ll set the code for the Pressed event on the SegmentedButton.</p>



<pre class="wp-block-preformatted">Sub Pressed(segmentIndex as integer) Handles Pressed
  PagePanel1.SelectedPanelIndex = segmentIndex
End Sub</pre>



<p>This will change the panel each time a button is pressed.</p>



<p>Now we’ll add a PanelChanged event to the container.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="844" height="730" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-17.png" alt="" class="wp-image-10036" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-17.png 844w, https://blog.xojo.com/wp-content/uploads/2022/02/image-17-300x259.png 300w, https://blog.xojo.com/wp-content/uploads/2022/02/image-17-768x664.png 768w" sizes="auto, (max-width: 844px) 100vw, 844px" /></figure>



<p>And name it PanelChanged.&nbsp;We’ll now implement the PanelChanged event on the PagePanel:</p>



<pre class="wp-block-preformatted">Sub PanelChanged() Handles PanelChanged
  RaiseEvent PanelChanged
End Sub</pre>



<p>Which will passes it along to the new PanelChanged event on the container.</p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Avoiding the TextChanged Event in Desktop Projects</title>
		<link>https://blog.xojo.com/2022/02/24/avoiding-the-textchanged-event-in-desktop-projects/</link>
		
		<dc:creator><![CDATA[Wayne Golding]]></dc:creator>
		<pubDate>Thu, 24 Feb 2022 19:24:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9740</guid>

					<description><![CDATA[Xojo Mobile and Web project controls don’t raise the TextChanged Event like Desktop controls do. But I want my code to be as similar as possible across all project types so I’ve created some custom controls. In this blog post I’ll walk you through the process of creating a Custom Desktop TextField control.]]></description>
										<content:encoded><![CDATA[
<p>Xojo Mobile and Web project controls don’t raise the TextChanged Event like Desktop controls do. But I want my code to be as similar as possible across all project types so I’ve created some custom controls. In this blog post I’ll walk you through the process of creating a Custom Desktop TextField control.</p>



<h3 class="wp-block-heading">Step 1</h3>



<p>Create a new Xojo Desktop project.</p>



<h3 class="wp-block-heading">Step 2</h3>



<p>Drag a TextField from the Library to the Navigator.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="1920" height="1080" src="https://blog.xojo.com/wp-content/uploads/2022/02/image1.gif" alt="" class="wp-image-10038"/></figure>



<h3 class="wp-block-heading">Step 3</h3>



<p>Add a private property userEntered As Boolean = True.&nbsp; This will be used to determine whether the user has entered the text, or if the text has been set via the application.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="902" height="564" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-1.png" alt="" class="wp-image-10018" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-1.png 902w, https://blog.xojo.com/wp-content/uploads/2022/02/image-1-300x188.png 300w, https://blog.xojo.com/wp-content/uploads/2022/02/image-1-768x480.png 768w" sizes="auto, (max-width: 902px) 100vw, 902px" /></figure>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="386" height="220" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-2.png" alt="" class="wp-image-10019" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-2.png 386w, https://blog.xojo.com/wp-content/uploads/2022/02/image-2-300x171.png 300w" sizes="auto, (max-width: 386px) 100vw, 386px" /></figure>



<h3 class="wp-block-heading">Step 4</h3>



<p>Add a method Value as below:</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="454" height="338" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-3.png" alt="" class="wp-image-10020" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-3.png 454w, https://blog.xojo.com/wp-content/uploads/2022/02/image-3-300x223.png 300w" sizes="auto, (max-width: 454px) 100vw, 454px" /></figure>



<p>Add the following code:</p>



<pre class="wp-block-preformatted">userEntered = False<br>Text = value<br>userEntered = True</pre>



<p>As you can see the userEntered property is set to false. The text is changed which will raise the TextChanged event and the userEntered property is set back to true.</p>



<h3 class="wp-block-heading">Step 5</h3>



<p>Add an Event Definition named TextChanged</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="526" height="650" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-4.png" alt="" class="wp-image-10021" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-4.png 526w, https://blog.xojo.com/wp-content/uploads/2022/02/image-4-243x300.png 243w" sizes="auto, (max-width: 526px) 100vw, 526px" /></figure>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="430" height="290" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-5.png" alt="" class="wp-image-10022" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-5.png 430w, https://blog.xojo.com/wp-content/uploads/2022/02/image-5-300x202.png 300w" sizes="auto, (max-width: 430px) 100vw, 430px" /></figure>



<h3 class="wp-block-heading">Step 6</h3>



<p>Add an Event Handler for TextChanged</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="520" height="640" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-6.png" alt="" class="wp-image-10023" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-6.png 520w, https://blog.xojo.com/wp-content/uploads/2022/02/image-6-244x300.png 244w" sizes="auto, (max-width: 520px) 100vw, 520px" /></figure>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="896" height="534" src="https://blog.xojo.com/wp-content/uploads/2022/02/image-7.png" alt="" class="wp-image-10024" srcset="https://blog.xojo.com/wp-content/uploads/2022/02/image-7.png 896w, https://blog.xojo.com/wp-content/uploads/2022/02/image-7-300x179.png 300w, https://blog.xojo.com/wp-content/uploads/2022/02/image-7-768x458.png 768w" sizes="auto, (max-width: 896px) 100vw, 896px" /></figure>



<p>Add this code:</p>



<pre class="wp-block-preformatted">If userEntered Then<br>&nbsp; RaiseEvent TextChanged<br>End If</pre>



<p>This method handles the default TextChanged event from the Super Class and if the userEntered property is true, raises the defined TextChanged event.</p>



<p>To use this control, you would drag it from the navigator or library onto your window or container as you would a normal TextField control.&nbsp;However, you can now set the text in the control using Value = “Some Text” and the TextChanged event won’t be raised.&nbsp;You can still set the Text property directly which will continue to raise the event.</p>



<p>For the sake of consistency I also have custom Web and Mobile TextFields that have the Value method.&nbsp;This allows the same code to be used on all project types.</p>



<p>You can also use this technique on other controls that automatically raise a “changed” event.</p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Simplified: Adding User Interface Controls at Runtime</title>
		<link>https://blog.xojo.com/2022/01/21/simplified-adding-user-interface-controls-at-runtime/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Fri, 21 Jan 2022 15:07:22 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9793</guid>

					<description><![CDATA[The process of adding new controls to windows (or containers) at runtime has been greatly simplified. Instead of having to deal with control arrays, when you use Xojo 2021r3 or later you can call the new AddControl method on the DesktopWindow (or DesktopContainer) where you want to add the new control. ]]></description>
										<content:encoded><![CDATA[
<p>The process of adding new controls to windows (or containers) at runtime has been greatly simplified. Instead of having to deal with control arrays, when you use Xojo 2021r3 or later you can call the new AddControl method on the DesktopWindow (or DesktopContainer) where you want to add the new control. Continue reading and I will show you how!</p>



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



<p>The new AddControl method on <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopwindow.html">DesktopWindow</a> and <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopcontainer.html">DesktopContainer</a> accepts any <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopuicontrol.html">DesktopUIControl</a> instance you want to add to a window or container.</p>



<p>To make the new DesktopUIControl instance really visible in the target window or container, you&#8217;ll need to set some basic properties; specifically the desired width and height values for the new instance control and also the left and top coordinate values where you expect the control to be added. These values are relative to the left/top corner of the target window/container, so a value of top = 0 and left = 0 means to add the control at the top/left corner of the target window itself.</p>



<p>In order to see how this works, this example creates a Desktop project that includes multiple DesktopButton instances at runtime while also removing them from the target DesktopContainer (calling the Close method on the instance to do that). Plus we&#8217;ll make them adjust as the size of the Container changes like you see in this example below.</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="618" height="442" src="https://blog.xojo.com/wp-content/uploads/2021/12/AddControl.gif" alt="" class="wp-image-9796"/></figure></div>



<h3 class="wp-block-heading">1. Creating the Base Container</h3>



<p>Open Xojo and create a new Desktop project. Double click on the Container in the Library so it is added to the Navigator in the IDE. Use the Inspector panel to change the following properties:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>BaseContainer</code></li></ul>



<p>Add a new property to the BaseContainer subclass in the Navigator (use the contextual menu for that), setting the following values in the Inspector panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>Controls()</code></li><li><strong>Type:</strong> <code>DesktopUIControl</code></li><li><strong>Scope:</strong> <code>Public</code></li></ul>



<h3 class="wp-block-heading">2. Adding New Controls to the BaseContainer</h3>



<p>We are going to need some Methods in the BaseContainer, starting with the one responsible for adding new DesktopButton instances. Add a new Method setting the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> <code>AddNewControl</code></li><li><strong>Scope:</strong> <code>Public</code></li></ul>



<p>Write the following snippet of code in the associated Code Editor for the Method:</p>



<pre class="wp-block-preformatted">// Setting static values for the new Button instances
// Width and Name values
Static cWidth As Integer = 40
Static cInitialName As String = "ControlName"

// Initial X and Y coordinates for the control instance
Var startX As Integer = If(Controls.Count = 0, 20, Controls(Controls.LastIndex).Left + cWidth + 20)
Var startY As Integer = If(Controls.Count = 0, 20, Controls(Controls.LastIndex).Top)

// We need to adjust the X/Y coordinates if the control
// exceeds the available BaseContainer width
If startX + cWidth &gt; Me.Width Then
  startX = 20
  startY = startY + Controls(Controls.LastIndex).Height + 20
End If

// Creating the new DesktopButton instance to be added
// and setting the expected values so it is visible
// at the desired size and position.
Var nControl As New DesktopButton
Var idxNumber As Integer = Controls.LastIndex + 1
nControl.Name = cInitialName + idxNumber.ToString
nControl.Caption = idxNumber.ToString
nControl.Left = startX
nControl.Top = startY
nControl.Width = cWidth

// On macOS we get the default height for free
// this is not the case on Windows
#If TargetWindows Then
  nControl.Height = 22
#EndIf

// We set the method to be called by the instance
// when the user presses the button
// so we can catch it and forward it to the
// BaseControl instance
AddHandler nControl.Pressed, AddressOf ControlActionCallback

// Adding the new control instance to the array
controls.Add(nControl)

// …and adding it to the BaseContainer
// calling the new AddControl method for that
Me.AddControl(nControl)</pre>



<p>As you can see, we are using the AddHandler method to substitute the original Event fired by the control with our own Method; so let&#8217;s create that. Add a new Method to BaseContainer using the following values in the Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>ControlActionCallback</code></li><li><strong>Parameters:</strong> <code>tControl As DesktopUIControl</code></li><li><strong>Scope:</strong> <code>Public</code></li></ul>



<p>And write this line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">RaiseEvent ControlPressed(tControl)</pre>



<h3 class="wp-block-heading">3. Removing Controls From the BaseContainer</h3>



<p>The third and last method we need to add to our BaseContainer subclass is the one responsible of removing the last added control; add a new method to the BaseContainer subclass using the following values:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> <code>RemoveLastControl</code></li><li><strong>Scope:</strong> <code>Public</code></li></ul>



<p>And write the following snippet of code in the associated Code Editor for the Method:</p>



<pre class="wp-block-preformatted">If Controls.LastIndex &lt;&gt; -1 Then

  Var tControl As DesktopUIControl = Controls.Pop

  // We need to remove the callback method from the original
  // Pressed event on the instance
  RemoveHandler DesktopButton(tControl).Pressed, AddressOf ControlActionCallback

  // Closing the control instance so it is removed from the
  // containing BaseControl
  tControl.Close

End If</pre>



<h3 class="wp-block-heading">4. Forwarding Events</h3>



<p>Because we are forwarding the received Pressed event from the DesktopButton to the ControlActionCallback method, and it is raising the ControlPressed method passing along the received instance, we need to define that Event in our BaseContainer subclass using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Event Name:</strong> <code>ControlPressed</code></li><li><strong>Parameters:</strong> <code>tControl As DesktopUIControl</code></li></ul>



<h3 class="wp-block-heading">5. Reacting to Resizing</h3>



<p>We want our BaseContainer to react to changes in its width and/or height, so it has the chance to change the layout (position) of the controls added to it. With the BaseContainer selected in the Navigator, add the Resizing Event and type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">#Pragma DisableBackgroundTasks
#Pragma DisableBoundsChecking

Var startX As Integer = 20
Var startY As Integer = 20

Var lastIndex As Integer = Controls.LastIndex
Var tControl As DesktopUIControl

For n As Integer = 0 To lastIndex

  tControl = Controls(n)

  If n &lt;&gt; 0 Then startX = Controls(n - 1).Left + Controls(n - 1).Width + 20

  If startX &gt; Me.Width - tControl.Width Then
    startx = 20
    If n &lt;&gt; 0 Then startY = startY + tControl.Height + 20
  End If

  tControl.Left = startX
  tControl.top = startY

Next n</pre>



<h3 class="wp-block-heading">6. Designing the User Interface</h3>



<p>Select the Window1 window in the Navigator so it is displayed in the Layout Editor. Next, drag a Button from the Library and place it at the top/left corner leaving the expected margins recommended by the Layout Guides.</p>



<p>With the just added button still selected, change the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>AddControlButton</code></li><li><strong>Caption:</strong> &#8220;Add Control&#8221;</li></ul>



<p>Add the Pressed Event to the button and type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">BaseContainer1.AddNewControl</pre>



<p>Add a second button and place it just below the previous one. Use the associated Inspector Panel to set the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>RemoveControlButton</code></li><li><strong>Locking:</strong> Left and Top locks closed</li><li><strong>Caption:</strong> &#8220;Remove Control&#8221;</li></ul>



<p>Use the resizing handlers on the control to make its width enough to display the Caption properly.</p>



<p>Add the Pressed Event to just added button and type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">BaseContainer1.RemoveLastControl</pre>



<p>Add a Label from the Library and place it to the right of the first button. Use the Inspector Panel to set the following values:</p>



<ul class="wp-block-list"><li><strong>Locking:</strong> Left and Top locks closed</li><li><strong>Text:</strong> &#8220;Control Pressed:&#8221;</li></ul>



<p>Use the resizing handlers on the control to make its width enough to display the Text properly.</p>



<p>Add a second Label and place it to the right of the previous one, using the Inspector Panel to set the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> <code>ControlPressedName</code></li><li><strong>Locking:</strong> Left and Top locks closed</li><li><strong>Text:</strong> &#8220;&#8221;</li></ul>



<p>Finally, drag the BaseContainer from the Navigator and place it below the second button. Use the resizing handlers on the control to make it width and tall enough to fill all the remaining area on the window. The final layout should look more or less like this:</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="791" src="https://blog.xojo.com/wp-content/uploads/2021/12/AddControlUI-1024x791.png" alt="" class="wp-image-9795" srcset="https://blog.xojo.com/wp-content/uploads/2021/12/AddControlUI-1024x791.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/12/AddControlUI-300x232.png 300w, https://blog.xojo.com/wp-content/uploads/2021/12/AddControlUI-768x593.png 768w, https://blog.xojo.com/wp-content/uploads/2021/12/AddControlUI.png 1346w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>Use the Inspector Panel to set the following values:</p>



<ul class="wp-block-list"><li><strong>Locking:</strong> left, top, right and bottom clocks closed (locked)</li></ul>



<p>With the BaseContainer1 instance selected in the Layout Editor, add the ControlPressed Event to it and write the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">ControlPressedName.Text = tControl.name</pre>



<h3 class="wp-block-heading">7. Running the App</h3>



<p>All set! Run the App, press the &#8220;Add Control&#8221; button to add as many buttons you want to the BaseContainer1 control, and press the &#8220;Remove Control&#8221; button to remove controls. Try to resize the window and you&#8217;ll see how the controls change their position as needed.</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>Desktop: Adding Controls at Runtime</title>
		<link>https://blog.xojo.com/2022/01/07/desktop-adding-controls-at-runtime/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Fri, 07 Jan 2022 21:58:01 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Control Set]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9876</guid>

					<description><![CDATA[If you have been using Xojo, you may be used to adding Controls at runtime using Control Sets. You  may not know it but beginning with Xojo 2021r3, there is a better way. Using the new Desktop Controls introduced in  Xojo 2021r3, you can add Controls to a DesktopWindow at runtime using AddControl, just like you do with Xojo Mobile and Web projects.]]></description>
										<content:encoded><![CDATA[
<p>If you have been using Xojo, you may be used to adding controls at runtime using <a href="https://documentation.xojo.com/topics/user_interface/desktop/desktop_controls/control_sets.html">Control Sets</a>. You may not know it but beginning with Xojo 2021r3, there is a better way. Using the <a href="https://blog.xojo.com/2021/11/18/new-desktop-controls/">new Desktop Controls</a> introduced in  Xojo 2021r3, you can add controls to a DesktopWindow at runtime using AddControl, just like you do with Xojo <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilescreen.html">Mobile</a> and <a href="https://documentation.xojo.com/api/user_interface/web/webpage.html">Web</a> projects.</p>



<p>Once you start using AddControl in your new Desktop projects (we definitely recommend that!) you&#8217;ll see it&#8217;s more convenient, plus you aren&#8217;t required to have a control to be used as a template already on the Window. </p>



<p>Related: Read &#8220;Simplified: <a href="https://blog.xojo.com/2022/01/21/simplified-adding-user-interface-controls-at-runtime/">Adding User Interface Controls at Runtime</a>&#8220;</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
