tag:blogger.com,1999:blog-74978479321068359502024-03-19T01:48:44.433-07:00The Raving RickThe diary of a dedicated Ubuntu user that lucked into his dream job working on the Ubuntu team.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.comBlogger179125tag:blogger.com,1999:blog-7497847932106835950.post-64664678162826019472014-07-22T05:56:00.000-07:002014-07-22T05:56:43.123-07:00The Community Team<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://images7.alphacoders.com/329/329979.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://images7.alphacoders.com/329/329979.jpg" height="200" width="320" /></a></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">So, given Jono’s departure a few weeks back, I bet a lot of folks have been wondering about the Canonical Community Team. For a little background, the community team reports into the Ubuntu Engineering division of Canonical, which means that they all report into me. We have not been idle, and this post is to discuss a bit about the Community Team going forward.</span></span></div>
<h2 style="text-align: left;">
<span style="font-weight: normal; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif; font-size: large;">What has Stayed the Same?</span></span></h2>
<div style="text-align: left;">
<span style="font-size: 15px; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">First, we have made some changes to the structure of the community team itself. However, one thing did not change. I kept the community team reporting directly into me, VP of Engineering, Ubuntu. I decided to do this so that there is a direct line to me for any community concerns that have been raised to anyone on the community team. </span></span></div>
<span style="font-size: 15px; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">I had a call with the Community Council a couple of weeks ago to discuss the community team and get feedback about how it is functioning and how things could be improved going forward. I laid out the following for the team.</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">First, there were three key things that I think that I wanted the Community Team to continue to focus on: </span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
</div>
<ul style="text-align: left;">
<li><span style="font-size: 15px; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Continue to create and run innovative programs to facilitate ever more community contributions and growing the community.</span></span></li>
<li><span style="font-size: 15px; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Continue to provide good advice to me and the rest of Canonical regarding how to be the best community members we can be, given our privileged positions of being paid to work within that community.</span></span></li>
<li><span style="font-size: 15px; line-height: 1.15; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Continue to assist with outward communication from Canonical to the community regarding plans, project status, and changes to those.</span></span></li>
</ul>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">The Community Council was very engaged in discussing how this all works and should work in the future, as well as other goals and responsibilities for the community team. </span></span></div>
<h2 style="text-align: left;">
<b style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif; font-size: large;">What Has Changed?</span></b></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">In setting up the team, I had some realizations. </span></span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">First, there was no longer just one “Community Manager”. When the project was young and Canonical was small, we had only one, and the team slowly grew. However, the Team is now four people dedicated to just the Community Team, and there are others who spend almost all of their time working on Community Team projects. </span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span>
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Secondly, while individuals on the team had been hired to have specific roles in the community, every one of them had branched out to tackle new challenges as needed.</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Thirdly, there is no longer just one “Community Spokesperson”. Everyone in Ubuntu Engineering can and should speak to/for Canonical and to/for the Ubuntu Community in the right contexts.</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">So, we made some small, but I think important changes to the Community Team.</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">First, we created the role </span><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>Community Team Manager</b></span><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Notice the important inclusion of the word </span></span><span style="color: black; font-family: Arial, Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">“</span><span style="color: black; font-family: Arial, Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Team</b></span><span style="color: black; font-family: Arial, Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">”. This person’s job is not to “manage the community”, but rather to organize and lead the rest of the community team members. This includes things like project planning, HR responsibilities, strategic planning and everything else entailed in being a good line manager. After a rather competitive interview process, with some strong candidates, one person clearly rose to the top as the best candidate. So, I would like formally introduce David Planella (<a href="https://plus.google.com/+DavidPlanella">lp</a>, <a href="https://plus.google.com/103521774287229204655/posts">g+</a>) as the Community Team Manager!</span><br />
<span style="color: black; font-family: Arial, Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Second, I change the other job titles from their rather specific titles to just “</span><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>Community Manager</b></span><span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">” in order to reflect the reality that everyone on the community team is responsible for the whole community. So that means, Michael Hall (<a href="https://launchpad.net/~mhall119">lp</a>, <a href="https://plus.google.com/+MichaelHall119/posts">g+</a>), Daniel Holbach (<a href="https://launchpad.net/~dholbach">lp</a>, <a href="https://plus.google.com/+DanielHolbach/posts">g+</a>), and Nicholas Skaggs (<a href="https://launchpad.net/~nskaggs">lp</a>, <a href="https://plus.google.com/+NicholasSkaggs/posts">g+</a>), are all now “Community Manager”. </span></span></div>
<h2 style="text-align: left;">
<b style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif; font-size: large;">What's Next?</span></b></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">This is a very strong team, and a really good group of people. I know them each personally, and have a lot of confidence in each of them personally. Combined as a team, they are amazing. I am excited to see what comes next.</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">In light of these changes, the most common question I get is, “Who do I talk to if I have a question or concern?” The answer to that is “anyone.” It’s understandable if you feel the most comfortable talking to someone on the community team, so please feel free to find David, Michael, Daniel, or Nicholas online and ask their question. There are, of course, other stalwarts like Alan Pope (<a href="https://launchpad.net/~popey">lp</a>, <a href="https://plus.google.com/+AlanPope/posts">g+</a>) and Oliver Grawert (<a href="https://launchpad.net/~ogra">lp</a>, <a href="https://plus.google.com/+OliverGrawert/posts">g+</a>) who seem to be always online :) By which, I mean to say that while the Community Managers are here to serve the Ubuntu Community, I hope that anyone in Ubuntu Engineering considers their role in the Ubuntu Community to include working with anyone else in the Ubuntu Community :)</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Want talk directly to the community team today? Easy, join their <a href="http://ubuntuonair.com/">Ubuntu on Air </a>Q&A Session at 15 UTC :)</span></span><br />
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">Finally, please note that I love to be "interrupted" by questions from community members :) The best way to get in touch with me is on freenode, where I go by rickspencer3. Otherwise, I am also on g+, and of course there is this blog :)</span></span></div>
</div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com169tag:blogger.com,1999:blog-7497847932106835950.post-56943404105561149382014-05-05T12:04:00.003-07:002014-05-05T12:04:30.534-07:00Delaying Queries to a Server from Map Move Events<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkaqtr1MfGkazRKWBALWzbQvgyIrmnYMKzH-3fDe0kHEM53-XhmoL0OfHUcfEdAiyG3tInV70ye7_lX2m31L86B1JNqEdxOH7gVulyYCVIqJF_iaEzSoU4jBDV_bxRYR-COOxIlc9cggY_/s1600/Screenshot+from+2014-05-05+14:50:49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkaqtr1MfGkazRKWBALWzbQvgyIrmnYMKzH-3fDe0kHEM53-XhmoL0OfHUcfEdAiyG3tInV70ye7_lX2m31L86B1JNqEdxOH7gVulyYCVIqJF_iaEzSoU4jBDV_bxRYR-COOxIlc9cggY_/s1600/Screenshot+from+2014-05-05+14:50:49.png" height="320" width="205" /></a></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Last week I added BikeShare info to my map. But I also take the bus a lot. I would like the information I need to choose between taking a bus and grabbing a bike. So I need to show buses on the map.
In my first iteration of showing bus data, I downloaded the XML for every bus stop in the metro system and loaded that. Unfortunately, this did not work. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">There are over 11,000 bus stops in the DC Metro System and using that may POI in a MapItemView made the map unusably slow. Even if it wasn't slow, when zoomed out on the map, the POI covered the map so it was just a huge blob of POI.
Oh well, looks like I need to do something slightly more elegant. </span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8kx-jjPxcMR2jaVpfi_JOeb9hXS9W9m8MR366hp-bT0iLy-ANGskAfvzdrd0-Kud547khA7qfEnVZxILcEx8L_kfCJAr_xFpAhPfCyCaX24Jv6JpKgiZsgJh93saFLazeinRYZHDCrUYH/s1600/Screenshot+from+2014-05-05+14:47:31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8kx-jjPxcMR2jaVpfi_JOeb9hXS9W9m8MR366hp-bT0iLy-ANGskAfvzdrd0-Kud547khA7qfEnVZxILcEx8L_kfCJAr_xFpAhPfCyCaX24Jv6JpKgiZsgJh93saFLazeinRYZHDCrUYH/s1600/Screenshot+from+2014-05-05+14:47:31.png" height="320" width="203" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">What I need to do is query the server every time the user moves the map, through a pan or a zoom and ask the web service for the XML for the bus stops centered on the center of the map, and within a certain radius that is slightly bigger than the map.
However, if I do that for each and eveyr pan and zoom, I end up hammering the server when ever the user swipes. The web service doesn't like to be called so much so fast, and it's just a waste of resources and bandwidth. So I decided to add a little logic to only load the data after the map is "at rest" for some period of time. I chose to start with a two second rest, but it could be whatever.
I did this by first creating a timer.
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">
Timer
{
id: mapRestTimer
running: false
interval: 2000
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Then I wrote add some event handlers to the Map, for zoom and pan events.
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> onZoomLevelChanged:
{
if(zoomLevel >= minimumBusDataZoomLevel)
{
timeMapRest()
}
}
onCenterChanged:
{
if(zoomLevel >= minimumBusDataZoomLevel)
{
timeMapRest()
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Note that I set it up so that bus stops aren't displayed if the user is panned out too far due to the problems I mentioned above. The timeMapRest function just decides whether it needs to restart the timer, or to start it. If the timer is already running, then the user has moved the map before the rest period was up, so we'll reset the timer. Otherwise, we'll go ahead and start the timer.
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function timeMapRest()
{
if(mapRestTimer.running)
{
mapRestTimer.restart()
}
else
{
mapRestTimer.start()
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">To finish up, I just had to write an onTriggered handler and set properties on my subclassed XmlListModel, which then goes ahead an updates itself based on the new latlong or zoom level.
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> id: mapRestTimer
running: false
interval: 2000
onTriggered:
{
//stop the timer and set the new latlong
running: false
//get the info necessary to calculate the correct radius
busStopListModel.latlong = [getThereMap.center.latitude,getThereMap.center.longitude]
var tr = getThereMap.toCoordinate(Qt.point(0,0))
var bl = getThereMap.toCoordinate(Qt.point(getThereMap.width,getThereMap.height))
var latdiff = bl.latitude - tr.latitude
var londiff = bl.longitude - tr.longitude
//TODO: fix this silly calculation for the radius
var rad = (latdiff > londiff) ? latdiff * (34.67 * 5280 / 3) : londiff * (34.67 * 5280 / 3 )
busStopListModel.mapRadius = rad
}
}
</code></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfSKr8PNXcBmwcI4_Gqs-3DhMUlMovUQ4LGJxdNoD7ut15y3f08TWur9USJUzc-0dzm_V-IkS2mGY6FjRu0aJ3QBCzYS8kKRpWEwVUQnvZcPhFQfVFZuXuGKw0fKrxURDIJnCYE4efz-15/s1600/Screenshot+from+2014-05-05+14:49:09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfSKr8PNXcBmwcI4_Gqs-3DhMUlMovUQ4LGJxdNoD7ut15y3f08TWur9USJUzc-0dzm_V-IkS2mGY6FjRu0aJ3QBCzYS8kKRpWEwVUQnvZcPhFQfVFZuXuGKw0fKrxURDIJnCYE4efz-15/s1600/Screenshot+from+2014-05-05+14:49:09.png" height="320" width="206" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The code for the whole project is <a href="https://code.launchpad.net/~rick-rickspencer3/+junk/GetThereDC">here</a>.</span></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com26tag:blogger.com,1999:blog-7497847932106835950.post-32644836275784097422014-04-21T08:30:00.002-07:002014-04-21T08:33:41.454-07:00Adding Interactivity to a Map with Popovers<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Arial, Helvetica, sans-serif;">On Friday I started my app "GetThereDC". I started by <a href="http://theravingrick.blogspot.com/2014/04/its-easy-and-fun-to-write-map-based-apps.html">adding the locations of all of the Bikeshare stations in DC to a map</a>. Knowing where the stations are is great, but it's a bummer when you go to a station and there are no bikes, or there are no empty parking spots. Fortunately, that exact information is in the XML <a href="https://www.capitalbikeshare.com/data/stations/bikeStations.xml">feed</a>, so I just need a way to display it.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">The way I decided to do it is to make the POI (the little icons for each station on the map) clickable, and when the user clicks the POI to use the Popover feature in the Ubuntu Components toolkit to display the data.
</span><br />
<h1>
<span style="font-family: Arial, Helvetica, sans-serif;"> Make the POI Clickable </span></h1>
<span style="font-family: Arial, Helvetica, sans-serif;">When you want to make anyting "clickable" in QML, you just use a <a href="http://developer.ubuntu.com/api/qml/sdk-14.04/QtQuick.MouseArea/">MouseArea component</a>. Remember that each POI is constructed as a delegate in the MapItemView as an Image component. So all I have to do is add a MouseArea inside the Image and respond to the Click event. So, not my image looks like this:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> sourceItem: Image
{
id: poiImage
width: units.gu(2)
height: units.gu(2)
source: "images/bike_poi.png"
MouseArea
{
anchors.fill: parent
onClicked:
{
print("The POI was clicked! ")
}
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">This can be used anywhere in QML to make an image respond to a click. MouseArea, of course, has other useful events as well, for things like onPressed, onPressAndHold, etc...
</span><br />
<h1>
<span style="font-family: Arial, Helvetica, sans-serif;"> Add the Roles to the XmlListModel </span></h1>
<span style="font-family: Arial, Helvetica, sans-serif;">I already know that I'll want something to use for a title for each station, the address, as well as the number of bikes and the number of parking slots. Looking at the XML I can see that the "name" property is the address, so that's a bonus. Additionally, I can see the other properties I want are called "nbBikes" and "nbEmptyDocks". So, all I do is add those three new roles to the XmlListModel that I constructed before:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> XmlListModel
{
id: bikeStationModel
source: "https://www.capitalbikeshare.com/data/stations/bikeStations.xml"
query: "/stations/station"
XmlRole { name: "lat"; query: "lat/string()"; isKey: true }
XmlRole { name: "lng"; query: "long/string()"; isKey: true }
XmlRole {name: "name"; query: "name/string()"; isKey: true}
XmlRole {name: "available"; query: "nbBikes/string()"; isKey: true}
XmlRole {name: "freeSlots"; query: "nbEmptyDocks/string()"; isKey: true}
}
</code></pre>
<h1>
<span style="font-family: Arial, Helvetica, sans-serif;"> Make a Popover Component </span></h1>
<span style="font-family: Arial, Helvetica, sans-serif;">The Ubuntu SDK offers some<a href="http://developer.ubuntu.com/api/qml/sdk-14.04/Ubuntu.Components.Popups/"> options for displaying additional information</a>. In old school applications these might be dialog boxes, or message boxes.
For the purposes of this app, Popover looks like the best bet. I suspect that over time the popover code might get a little complex, so I don't want it to be too deeply nested inside the MapItemView, as the code will become unwieldy. So, instead I decided to add a file called BikeShareStationPopover.qml to the components sub-directory. Then I copy and pasted the <a href="http://developer.ubuntu.com/api/qml/sdk-14.04/Ubuntu.Components.Popups.Popover/">sample code in the </a><span style="color: #0000ee;"><u>documentation</u></span> to get started. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">To make a popover, you start with a Component tag, and then add a popover tag inside that. Then, you can put pretty much whatever you want into that Popover. I am going to go with a Column and use<a href="http://developer.ubuntu.com/api/qml/sdk-14.04/Ubuntu.Components.ListItems/"> ListItem components</a> because I think it will look nice, and it's the easiest way to get started. Since I already added the XmlRoles I'll just use those roles in the construction of each popover. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Since I know that I will be adding other kinds of POI, I decided to add a Capital Bike Share logo to the top of the list so users will know what kind of POI they clicked. I also added a close button just to be certain that users don't get confused about how to go back to the map. So, at the end of they day, I just have a column with ListItems:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> import QtQuick 2.0
import Ubuntu.Components 0.1
import Ubuntu.Components.ListItems 0.1 as ListItem
import Ubuntu.Components.Popups 0.1
Component
{
id: popoverComponent
Popover
{
id: popover
Column
{
id: containerLayout
anchors
{
left: parent.left
top: parent.top
right: parent.right
}
ListItem.SingleControl
{
control: Image
{
source: "../images/CapitalBikeshare_Logo.jpg"
height: units.gu(5)
width: units.gu(5)
}
}
ListItem.Header { text: name}
ListItem.Standard { text: available + " bikes available" }
ListItem.Standard { text: freeSlots + " parking spots available"}
ListItem.SingleControl
{
highlightWhenPressed: false
control: Button
{
text: "Close"
onClicked: PopupUtils.close(popover)
}
}
}
}
</code></pre>
<h1>
<span style="font-family: Arial, Helvetica, sans-serif;">Make the Popover Component Appear on Click</span></h1>
<span style="font-family: Arial, Helvetica, sans-serif;">So, now that I made the component code, I just need to add it to the MapItemView and make it appear on click. So, I add the tag and give it an id to the MapQuickItem Delegate, and change the onClicked handler for the MouseArea to open the popover:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> delegate: MapQuickItem
{
id: poiItem
coordinate: QtPositioning.coordinate(lat,lng)
anchorPoint.x: poiImage.width * 0.5
anchorPoint.y: poiImage.height
z: 9
sourceItem: Image
{
id: poiImage
width: units.gu(2)
height: units.gu(2)
source: "images/bike_poi.png"
MouseArea
{
anchors.fill: parent
onClicked:
{
PopupUtils.open(bikeSharePopover)
}
}
}
BikeShareStationPopover
{
id: bikeSharePopover
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">And when I run the app, I can click on any POI and see the info I want! Easy!</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQG5qo2ABlfZHgH6RyQpXp2iMRFS67zV0D5W8UZLIeJhjhezB58v7V0cMv_uKqXcosJxg0OmCeP2sA0_9PQZY5cFsDz9HWBeIykFYpTaitwBgv9dOkF_LuJG9fyBMxiFwQbvUoUY5J2JNQ/s1600/Screenshot+from+2014-04-21+11:22:52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQG5qo2ABlfZHgH6RyQpXp2iMRFS67zV0D5W8UZLIeJhjhezB58v7V0cMv_uKqXcosJxg0OmCeP2sA0_9PQZY5cFsDz9HWBeIykFYpTaitwBgv9dOkF_LuJG9fyBMxiFwQbvUoUY5J2JNQ/s1600/Screenshot+from+2014-04-21+11:22:52.png" height="320" width="213" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;"><a href="https://code.launchpad.net/~rick-rickspencer3/+junk/GetThereDC">Code is here</a></span></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com37tag:blogger.com,1999:blog-7497847932106835950.post-85769951752572637182014-04-18T06:10:00.000-07:002014-04-18T06:10:36.586-07:00It's Easy and Fun to Write Map Based Apps<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Arial, Helvetica, sans-serif;">Yesterday I started work on an app that I personally want to use. I don't have a car, so I use services like Metro Bus, Metro Rail, Car2Go, and BikeShare around DC all the time. It's annoying to go to each different web page or app to get the information that I want, so I decided to write an app that combines it all for me in one place.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">After asking around, I settled on a best practice for Ubuntu map apps, and I was pointed to this excellent code as a basis:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://bazaar.launchpad.net/~yohanboniface/osmtouch/trunk/view/head:/OSMTouch.qml">http://bazaar.launchpad.net/~yohanboniface/osmtouch/trunk/view/head:/OSMTouch.qml</a></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">It was so easy and fun once I got started, that I decided to show the world. So, here we go.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I started with a "Simple UI" project. Then I deleted the default column that it started with, and I set the title of the Page to an empty string. While I was at it, I changed the height and width to be more like a phone's dimensions to make testing a little easier. So my starter code for an emply Window looks like this:</span></div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> import QtQuick 2.0
import Ubuntu.Components 0.1
import "components"
MainView {
objectName: "mainView"
applicationName: "com.ubuntu.developer.rick-rickspencer3.MapExample"
width: units.gu(40)
height: units.gu(60)
Page
{
title: i18n.tr("")
}
}
</code></pre>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;">So what's missing now is a map. First I need to import the parts of Qt where I get location and map information, so I add these imports:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> import QtPositioning 5.2
import QtLocation 5.0
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Then I can use the Map tag to add a Map to the MainView. I do four things in the Map to make it show up. First, I tell it to fill it's parent (normal for any component). Then I set it's center property. I choose to do this using a coordinate. Note that you can't make a coordinate in a declarative way, you have to construct it like below. The center property tells the map the latitude and longitude to be centered on. Then I choose the zoom level, which determines the scale of the map. Finally, I need to specify the plug in. For various reasons, I choose to use the Open Street Maps plugin, though feel free to experiment with others. So, a basic funcitonal map looks like this:
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Page
{
title: i18n.tr("")
Map
{
anchors.fill: parent
center: QtPositioning.coordinate(38.87, -77.045)
zoomLevel: 13
plugin: Plugin { name: "osm"}
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">When I run it, I get a lot of functionality for free. On the desktop I can drag the map, and when I run the app on my phone or tablet, I can pinch to zoom in or out. All that functionality comes for free. Of course, you are free to add mapping controls as desired, but I find that map works well out of the box, at leas</span><span style="font-family: Arial, Helvetica, sans-serif;">t on a device that supports pinch and zoom.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuCjUnhqbDAH5jftMxjfiSCi4kLODN0cpFE_yMU2_SPeAIu3S0MHJINojjMC8XWH0fNg5CVx0cSuQ6hHdqzlZUBCslwcMZMs11ZaJFIeI4NtPQMapZ5oozHwXR-ToHXM0goYw0JGY1zBK3/s1600/map1.png" height="320" width="213" /><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Typically, a map displays little pinpoints. These are often referred to as Points of Interest, or more typically "POI". It's delightfully easy to populate your map with POI using our old friend XmlListModel. First, you will need some XML that has location information. For this exmaple, I am going to use the Bike Share feed for Washington, DC. It's easy to get and to parse, so it makes a nice example. You can see the feed here:</span><br />
<a href="https://www.capitalbikeshare.com/data/stations/bikeStations.xml"><span style="font-family: Arial, Helvetica, sans-serif;">https://www.capitalbikeshare.com/data/stations/bikeStations.xml</span></a><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">So let's use it to set up our XmlListModel. First, of course, we need to import the XmlListModel functionality.</span><br />
<br />
<br /></div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> import QtQuick.XmlListModel 2.0
</code></pre>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;">Next, we'll make the list model, and use the query and Roles functionality to set up the model with the latitude and longitude of each POI inside the model. This is *exactly* like using the XmlListModel for a typical list view. Very cool.
</span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> XmlListModel
{
id: bikeStationModel
source: "https://www.capitalbikeshare.com/data/stations/bikeStations.xml"
query: "/stations/station"
XmlRole { name: "lat"; query: "lat/string()"; isKey: true }
XmlRole { name: "lng"; query: "long/string()"; isKey: true }
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Now that I have my list model set up, it's time to display them on the Map. We don't do that with a ListView, but rather wtih a MapItemView. This works exactly the same as a ListView, except it displays items on a map instead of in a list. Just like a ListView I need a delegate that will translate use data from the each item in the XmlListModel to create a UI element. In this case, it's a MapQuickItem instead of a ListItem (or similar). A MapQuickItem needs to know 4 things.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<ol style="text-align: left;">
<li><span style="font-family: Arial, Helvetica, sans-serif;">The model where it will get the data. In this case, it's my XmlListModel, but it could be a javascript list or other model as well.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A latitude and longitude for the POI, which I set up as roles in the XmlListModel.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">An offset for whatever I am using for POI so that it is positioned properly. In this case I have made a little pushpin image out of the bikeshare logo (I know it's bad I'll make a better one later :) ). The offset is set by anchorPoint, so I make the anchorPoint the bottom and center of of the pushpin. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Something to use for the POI. In this case, I choose to use an image. Note that it is important to use grid units, or the POI may appear too small on some devices, and too large on others. Grid Units make them "just right" on all devices, and ensure that users can click them on any device. </span></li>
</ol>
<br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">So, here is my MapItemView that goes *inside* the Map tag. It's a MapItemView for the map, after all.
</span><br />
<br /></div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> MapItemView
{
model: bikeStationModel
delegate: MapQuickItem
{
id: poiItem
coordinate: QtPositioning.coordinate(lat,lng)
anchorPoint.x: poiImage.width * 0.5
anchorPoint.y: poiImage.height
sourceItem: Image
{
id: poiImage
width: units.gu(2)
height: units.gu(2)
source: "bike_poi.png"
}
}
}
</code></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Now when I run the app, the POI are displayed. As you would expect, when the user moves the Map, the MapItemView automatically displays the correct POI. It's really that easy.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJW4VLFr14gtBVEXBvzsxn1YfHFR133y-4Mxrn3PoIAUIh5VD9ScT8J2HL-RTofP_LJR70GLEhLC_AXplW585fWc0jbc-GtfH8xtAexkQq4uylWDHJuFk6imXVvANvqWW-RfuYptwQTvVZ/s1600/map2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJW4VLFr14gtBVEXBvzsxn1YfHFR133y-4Mxrn3PoIAUIh5VD9ScT8J2HL-RTofP_LJR70GLEhLC_AXplW585fWc0jbc-GtfH8xtAexkQq4uylWDHJuFk6imXVvANvqWW-RfuYptwQTvVZ/s1600/map2.png" height="320" width="213" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaBGkNSyNnHy1z6fcV8uv0rPKdIlqVho0gxE2iaP-RqJiP-YyiIv_HS_-QcWsD-GYa8b_TQz_56rzQOI5_IlOWQd6vqstSu1x6QMAsl4Cg32OBlUhSVueh2F5T3lEz88AbmqW37kO42WtY/s1600/map3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaBGkNSyNnHy1z6fcV8uv0rPKdIlqVho0gxE2iaP-RqJiP-YyiIv_HS_-QcWsD-GYa8b_TQz_56rzQOI5_IlOWQd6vqstSu1x6QMAsl4Cg32OBlUhSVueh2F5T3lEz88AbmqW37kO42WtY/s1600/map3.png" height="320" width="213" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">If you want to add interactivity, that's easy, you can simply add a MouseArea to the Image and then use things like Ubuntu.Components.Popups to popup additional information about the POI. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">This sample code is here: <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/MapExample/view/head:/MapExample.qml">http://bazaar.launchpad.net/~rick-rickspencer3/+junk/MapExample/view/head:/MapExample.qml</a></span></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com209tag:blogger.com,1999:blog-7497847932106835950.post-41747976719306515222013-10-17T07:37:00.001-07:002013-10-17T07:37:05.466-07:00Rick's Ubuntu for Phones FAQ<div dir="ltr" style="text-align: left;" trbidi="on">
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Why is the Ubuntu Team So Excited about Ubuntu for Phones?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">13.10 represents a major step forward for the Ubuntu project, because the Ubuntu phone images feature a set of new technologies that solve many of the longstanding difficulties with Ubuntu distros. Specifically:</span></div>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Image based updates</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A complete SDK</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Application Isolation</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Click packages and click installer with app store</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Mir Display Server and Window Manager</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Unity 8</span></div>
</li>
</ol>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Image based updates</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Image based updates are a new of getting updates on Ubuntu. In the past, all versions of Ubuntu (and on Ubuntu Server and Desktop for 13.10 and beyond) updates were done with apt. Apt is the tool for debian package management. It was capable of calculating which packages needed to be updated or upgraded, and then ran those updates. Apt works well on servers and desktops because it supports complicated dependencies. However, it also takes a lot of computing horsepower to compute the updates or upgrades, and due to it being complicated, could occasionally get into situations that needed to be fixed with some command line options. </span></div>
<b id="docs-internal-guid-591e173e-c6d8-bba1-d4b3-b94c85883104" style="font-weight: normal;"><br /><span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></b>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu needed to take much less energy and time to perform updates, and needed to be much more reliable. This is where image-based updates come in. The Ubuntu images for phones have a read only file system by default, and a specific partitioning scheme for the drives. User data and applications are kept on a separate partition from the underlying system. As a result, if our update servers know which build you are running, they have an exact copy of the system on the servers. So rather than calculating package upgrade paths on your computer, the server can simply calculate a binary diff and the phone downloads only the diff for the system. Ubuntu then applies the diff and reboots into the update image. This has the added benefit that the downloads of the updates are much smaller, since users only have to download what has changed.</span></div>
<b style="font-weight: normal;"><br /><span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></b>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">This all happens over the air. You can access this function from the Updates panel of the system settings application. Note that the phone can still be put into “system builder mode” which allows a user full access to all of the power of Apt, if they want to hack on their phones.</span></div>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A Complete SDK</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu for phones provides three ways of developing applications for end users:</span></div>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Web apps</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Phone gap</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu SDK</span></div>
</li>
</ol>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Web apps and phone gap support is tried and true technology for delivering HTML 5 applications to end users and we are proud to offer these options to developers. But what if you want to write a native app that looks like the core Ubuntu applications? Ubuntu now offers an SDK which includes the QtCreator development environment, the Qt library, the Ubuntu UI Toolkit, and many Ubuntu services, such as the Friends API for writing socially connected apps.</span></div>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Application Isolation</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu on the phone runs applications under App Armour. App Armour is a kernel feature which ensures that processes are simply not able to access any resources to which they are not entitled. In this way, application are kept from interfering with each other or the underlying system in any way. This keeps the user safe from both malicious applications that may try to snoop on other applications, use services to which they are not entitled, or other naughtiness. Developers can write applications that interact with other applications, but only through strictly defined and secure APIs. </span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">One result of this much higher level of isolation, is that applications do not need to go through the same degree scrutiny to ensure that they are safe. As such, we can publish new applications to stable releases orders of magnitude faster than ever before. It often takes less than 30 minutes for an application to be submitted, reviewed, and appear in the application store.</span></div>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Click Packages</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu for phones offers a brand new and much simpler means of packaging and installing applications. For other Ubuntu images, apps needed to be packaged as debian files (.deb files). This required the developer to have significant skill in packaging in order to manage the dependencies. </span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Click packages are much simpler because applications can depend only upon the “base sdk” which is installed on all phones, or on libraries bundled directly with the application. Since click packages are uploaded to the store and run under application isolation, it is very easy and fast for an application developer to get their applications to users.</span></div>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Mir Display Server and Window Manager</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Ubuntu Desktop has always depended on implementations of the X11 protocol (xorg). This technology is more than 20 years old and designed for very different systems than are available today. Between the complexity of the protocol and the drivers, it is a significant effort to deliver a stable and fast system to end users. Even with this effort, their systems sometime regress or break, especially if the users are using drivers from their GPU chip vendor. Writing a window manager on top of this protocol also turned out to be very complex, often due to differences in the implementations of APIs in the GPU drivers, and also due to complexities in the X11 protocol.</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Mir display server solves these problems by offering a simpler and more direct library to both GPU driver developers and Window Manager authors. Mir is also designed to work easily with existing Android drivers.</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Mir display server on Ubuntu for phones is carefully designed by the Ubuntu design team, and takes advantage of the simpler more direct Mir API to deliver faster development and a better user experience.</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Mir display server and window manager are currently optimized for phones and to some degree tablets, but will grow over the next few releases to provide a full desktop experience as well.</span></div>
<h2 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Unity 8</span></h2>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Finally, Ubuntu phone images feature the latest version of the Ubuntu shell, called “Unity 8”. It features enhancements to the launcher and to indicators that make them very user friendly even when operated with just a thumb while holding a phone, as well as the latest iteration of the dash that includes scopes optimized for mobility, providing touch optimized access to music, video, and applications.</span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">What is “Ubuntu Touch”?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">“Ubuntu Touch” is the development codename for the special images of Ubuntu that were created to run on phones and tablets. There are some technical differences in terms of how the phones are updated, which apps can run and how they are installed, and the display server. However, these differences are small compared to the similarities. Officially, these images are simply named “Ubuntu”.</span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">How Do I Get and Use Ubuntu on a Phone?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Ubuntu 13.10 will have images that work for the Galaxy Nexus and the Nexus 4. They are available in the normal places. However, phones require special steps for installing a new OS. Aside from the officially supported images, the community has created a set of ports for their own devices, you can find that list here: </span><a href="https://wiki.ubuntu.com/Touch/Devices" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://wiki.ubuntu.com/Touch/Devices</span></a><span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Will Ubuntu Work on My Tablet?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We are making Ubuntu images for the first version of the Nexus 7 and the Nexus 10. These images are available alongside images for phones, and the installation experience is similar. However, please note that we in Ubuntu prioritized making Ubuntu working for phones for 13.10, so the tablet images are still in “early preivew stages” There are bugs and missing functionality. We plan to focus on tablets more fully for 14.04.</span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Is Ubuntu Finished for Phones?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Yes and no. We are proud that Ubuntu 13.10 is a complete 1.0 solution for powering your phone. Many of us have been using Ubuntu as our on our only phone for months. However, it does have one or two features that you may miss and that will be added very soon. For example, Ubuntu 13.10 does not have a lock screen when running on a phone. There are some settings, such as a convenient airplane mode that have not been implemented yet, but will be shortly.</span></div>
<b style="font-weight: normal;"><br /><span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></b>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Of course, we also have a list of enhancements and new features for the 14.04 as well!</span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">If I Install Ubuntu on my Phone, How Will it be Supported?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The images for phones feature a new way to update that we call “image based updates”. For about a month after we release 13.10, expect to get updates for only the most critical bugs. However, after about a month, all users will be upgraded to the current development version. This will allow users to get the latest features and bug fixes without having to wait six months. </span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Can I Run my Favorite Application on My Phone?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">This depends on the application. If your favorite app is a web app, then you are in luck. Ubuntu ships many web applications in a manner that is well integrated into the overall phone experience. Also, there is a good chance that your favorite application has a version made especially to run on phones running Ubuntu. However, applications that require a keyboard and mouse, or that require a toolkit that is not supported on Ubuntu will not run on the phone until it is ported.</span></div>
<h1 dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 21px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Can I Run a Desktop from My Phone Like I’ve Seen in Demos?</span></h1>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">This represents our ultimate goal for what what we call “convergence”, one device with all the functionality you need from various devices converged together. In 13.10 we have made great strides towards convergence. Most of the software running on Ubuntu for desktop images and Ubuntu for phone images is the same. However, Ubuntu does not yet have the capability for a phone to dock into a desktop, yet. We continue to work very hard toward this goal, and all of our development is geared towards reaching it. </span></div>
<br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com95tag:blogger.com,1999:blog-7497847932106835950.post-48851157495497443512013-08-08T04:17:00.000-07:002013-08-08T04:49:34.037-07:00The Big Rocks of August<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://ih.constantcontact.com/fs054/1101110503932/img/268.jpg?a=1107362772692" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="http://ih.constantcontact.com/fs054/1101110503932/img/268.jpg?a=1107362772692" width="320" /></a></div>
<br />
<br />
Have you ever heard the phrase "If you don't put the big rocks in first, you'll never get them in at all"? It's from an <a href="http://www.csub.edu/tlc/options/resources/handouts/teach_strat/putinrocks.html">oft repeated parable</a> about life and also project management.<br />
<br />
Last week I met with Canonical's Ubuntu Engineering leadership team (me, the Directors, Engineering Managers, Tech Leads, and Architects). We took a close look at the progress of Ubuntu Touch from many points of view. All in all, I left last week feeling quite satisfied that Ubuntu Touch for phones was on track for a very good 1.0 release in October. However, we identified that there were some "big rocks" that we didn't get in the jar yet, and that we needed to get them in asap if we were going to finish with the kind of systematic development process that will be necessary to make 13.10 rock.<br />
<br />
So, we set the goal for August to get all the big rocks in. The 5 big rocks ...<br />
<h2 style="text-align: left;">
Image Based Upgrades</h2>
<a href="https://blueprints.launchpad.net/ubuntu/+spec/foundations-1305-image-based-updates">Blueprint is here</a><br />
<br />
The first big rock is Image Based Upgrades. Today, when we "bless" a new image, one must use a tool on your desktop called "phablet-flash" to update to that new image. After August, the phone will download updates over wireless and install them without requiring a connection to the desktop. As you can see in the blueprint, this requires some deep changes to the way Ubuntu works (as well as to our automated testing) in order to do it as robustly as is necessary for this market (a.k.a. no "dpkg --configure -a"). The disks must be partitioned so that the system is total separate from user data. The server must calculate the binary diff of an update for that partition, and the diff must be applied safely and reliably.<br />
<br />
All of this work is in place now on the client and server and being tested. Wet need to bring it together and start using it. We will do so in August.<br />
<h2 style="text-align: left;">
Indicators</h2>
Ubuntu touch is designed to support user settings in 2 ways. The most common and dynamic settings are available from the indicators, others from the settings application.<br />
<br />
The settings application has a long tail of settings, some more important than others. The indicators, have limited, but critical functionality. By the end of August, all of the indicators will be functional. As a result, most of the back-end work will be in place to finish settings in September and October as well.<br />
<h2 style="text-align: left;">
Click</h2>
Martin Albeseti is working on a new video, but there is as starter one here if you want to <a href="http://www.youtube.com/watch?v=BjGAnV33GHU">see an end to end demo</a>.<br />
<br />
How developers write applications, how users install applications, and how those applications run ... what a huge topic. By the end of August, Ubuntu Touch will be doing this in a different and new way.<br />
<br />
Of course, we all know that developers will use <a href="http://developer.ubuntu.com/get-started/">the sweet Ubuntu SDK</a> to get write their sweet apps ;) However, did you know that developers will not need to package those apps into deb files? Rather they will make a simple<a href="https://blueprints.launchpad.net/ubuntu/+spec/foundations-1305-click-package"> click package</a> that includes their code and all of their dependencies (in the case that they have dependencies that are not part of the SDK). Click packages are easy to create with Click, and support for this is even built into Qt Creator. So writing and packaging an app is now, finally, fun and easy for Ubuntu Touch.<br />
<br />
But how will users find applications to install in Ubuntu Touch? Developers will be able to upload their applications and after a very quick review to ascertain that the requested permissions (more on that below) are reasonable, users will be able to find their apps in the apps lens! What could be easier. With a simple button click in the dash, the application will be downloaded and installed by Click.<br />
<br />
The reason we can do such a light review is due to the something called "<a href="https://wiki.ubuntu.com/SecurityTeam/Specifications/ApplicationConfinement">application confinement</a>" which has already landed and is running on Ubuntu Touch today. Application confinement causes an application to run under apparmour, which means that the kernel controls what it has access to. As such, it is very very difficult for an application to do anything naughty.<br />
<br />
Now, an application that is totally confined may be useful, but it may be desirable for an app to interact with data from other apps. For example, what if you wanted to import a picture from the phone? To support that, there will be a series of trusted helpers and services which can securely provide an application the data that it needs with a few simple SDK calls.<br />
<br />
After August, when Click is working end to end on the phone, we can spend September and October adding the rest of the important features, like updating applications.<br />
<h2 style="text-align: left;">
Application Lifecycle</h2>
Speaking of SDK calls, how do applications behave on the phone? On the desktop, an application can just run and run, because they have big batteries and are normally plugged in. So, a traditional Linux desktop does nothing to manage an application's use of resources.<br />
<br />
This can't work on a phone. The reason this can't work is that phones have small batteries and are rarely plugged in. So a typical phone OS does not allow applications to just do what they want.<br />
<br />
For Ubuntu Touch, when an application is put into the background today, it is stopped. Not killed, just stopped. The app can't use any resources and is essentially "frozen in time" until it comes to the front again. This ensures that a crazy application is only consuming resources when it is in the front, where the user is using.<br />
<br />
But we have some work to do in August to finish the application lifestyle. First, what happens when you have so many applications open that there is no more memory? The OS has to do something to make room. In Ubuntu Touch, the OS will kill any stopped applications that haven't been used in a while in the case of low memory. But wait! you say. Won't that mean my apps get killed and I have to relaunch them and lose all my work and everything?<br />
<br />
The answer to this problem is simple, when an application goes into the background, it will get a signal and a little time. The application can use the time to save whatever info it needs to rebuild itself in the case it gets killed while it is in the background. When the app gets called to the foreground, it can then use a little time to read whatever info it saved and rebuild itself. The result for the user will be that the app appears to just keep on running. Nice!<br />
<br />
But Wait! What about apps that should work in the background? For example, the Music Player should keep playing while it is in the background, right? The answer to this is "sort of". An app shouldn't do anything that it would want to do in the background, but it should rather use services that work outside the scope of any one app. So the Music Player shouldn't make function calls to play music, but should rather call a system service and tell the system service what music to play.<br />
<br />
There are several services like this that we will need in place by end of August, these include:<br />
<div style="text-align: left;">
</div>
<ol>
<li>Music</li>
<li>Download</li>
<li>Telephony</li>
<li>Alarms (time)</li>
<li>Friends</li>
<li>Content</li>
<li>URI Handler</li>
<li>NITZ</li>
<li>Contacts</li>
</ol>
These services are "complete" when one can use them from the Ubuntu SDK.<br />
<h2 style="text-align: left;">
Unity 8/Mir</h2>
Finally, Unity 8 (for phone only right now) is in the archive. Mir is almost in the archive. It's time to get these into the phone images so that we can spend September and October doing some nice refinements!<br />
<h2 style="text-align: left;">
Conclusion</h2>
Of course not everyone in the Ubuntu community is working solely on these big rocks. So lots of other exciting stuff will happen as well. However, It's important that we get these 5 big rocks done in August. That will leave us September and part of October for us to work on the remaining list of features and requirements in priority order. After August, Ubuntu Touch will have made a dramatic step forward, really becoming the architecture that it is meant to be. I can't wait!<br />
<br /></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com26tag:blogger.com,1999:blog-7497847932106835950.post-55122459338455992992013-06-12T11:33:00.000-07:002013-06-12T12:34:59.404-07:00Passing and Being Passed<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMFPU9usvKRzfXXyRNMOHOpGwLX7OLJpwCFUiATwKV8WIb5sprYEEwlrLpeKm7jLJj64glQiuvGTn_p-m9LJI6kNdPnlQ8f923GbjykOYUnAwviCy-0nEbPFiPO7aKnfT1ZNfKgx9rhmPP/s1600/image20130520_0001.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMFPU9usvKRzfXXyRNMOHOpGwLX7OLJpwCFUiATwKV8WIb5sprYEEwlrLpeKm7jLJj64glQiuvGTn_p-m9LJI6kNdPnlQ8f923GbjykOYUnAwviCy-0nEbPFiPO7aKnfT1ZNfKgx9rhmPP/s320/image20130520_0001.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Buckley. A dog I get to pet, but do not have to walk!</td></tr>
</tbody></table>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-large;">Co-Working Change My Life</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">I got some feedback from my wife and kids last week that I seem generally happier and more "tuned in" when I am at home than I have in the past few years. Additionally I have been feeling much more productive at work. I chalk these changes up almost totally to adopting a co-working lifestyle.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I'm sure you are all away that Canonical is mostly a distributed company. We work from all over the world in online spaces. This is great. It has meant that I have gotten to know people from all the world. I've learned a little French. I make my own schedule. Working for a distributed company has been so enriching in so many ways, I don't see how I could ever go back to a real office environment.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Working for a distributed company has also meant that I have been working at home the last 4+ years. In many ways, this has been great. I've spent zero hours commuting, as one small example. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"><a href="http://officenomads.com/">Office Nomads</a></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Z0VBKZpusEUDq6klFIBaTzEwGsY-U7PodxJYyNPbdEBU89MUfOQ287CvTqc91FGmNahYkZelz9Lzxqv0Yl_B1SW2Ljc6n1zEsNUD4AipHL381f2EsErzBv4TG9f1J-eOrpbsJuKyYpft/s1600/image20130612_0001.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Z0VBKZpusEUDq6klFIBaTzEwGsY-U7PodxJYyNPbdEBU89MUfOQ287CvTqc91FGmNahYkZelz9Lzxqv0Yl_B1SW2Ljc6n1zEsNUD4AipHL381f2EsErzBv4TG9f1J-eOrpbsJuKyYpft/s320/image20130612_0001.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The friendly and helpful proprietors of Office Nomads</td></tr>
</tbody></table>
<span style="font-family: Arial, Helvetica, sans-serif;">For various reasons, I decided to give co-working a try, and I am surprised how well I have taken to it. Co-working means that I "go to work" in a large shared office space. Practically, it means that I share resources such as networking, printers, desks, dogs, etc... </span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj220NMYC_wvViMRwiqWWbBAzdgC7ciN4pY2Id8QbevB2P33P0OMxHOOLoiRADIBSoejZd5bnYPzwjBCEe_E_1gnhFpmjM6x-wJrt1Edafoj6MkisQibiccsXQbGG9C2BUSen4bUnmAO12H/s1600/image20130612_0005.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj220NMYC_wvViMRwiqWWbBAzdgC7ciN4pY2Id8QbevB2P33P0OMxHOOLoiRADIBSoejZd5bnYPzwjBCEe_E_1gnhFpmjM6x-wJrt1Edafoj6MkisQibiccsXQbGG9C2BUSen4bUnmAO12H/s320/image20130612_0005.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Some nomads doing their thing</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggUZMJ4XBXaJrsieUVAaPOBpoKLLfMnriyp4nIfJfQjD7UPwYqGmotiykXl2JyDW3ls4G-FtAjieCn-GQ4ladrTdqxPKvnAzA3CdKXTs4LDasmINfQwcNynLIMnkJ3lald41fOBzF5xJXC/s1600/image20130612_0008.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggUZMJ4XBXaJrsieUVAaPOBpoKLLfMnriyp4nIfJfQjD7UPwYqGmotiykXl2JyDW3ls4G-FtAjieCn-GQ4ladrTdqxPKvnAzA3CdKXTs4LDasmINfQwcNynLIMnkJ3lald41fOBzF5xJXC/s320/image20130612_0008.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The area where I work. I usually take the standing desk to the left.</td></tr>
</tbody></table>
<div style="text-align: center;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<div style="text-align: left;">
On the impractical side, it means that I share in the positivity of other people also doing what they love. Hearing people work, chatting with folks when I get in, having lunch with other people, etc... This has all been great for me, personally. I think there is a certain element of just getting out of the house and not being isolated. But the atmosphere at Office Nomads is high productivity, and I can't help but to feed off the buzz. I think the community building aspects of their mission is harmonious with my values, as well.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTzc6eODCk4gdNlQTy6MY2LXr68l-xMkXnmiz74tNSig4e_NRBDj7yWyFTzMdz_jJKTL-o02bqI_cgyOnf8a-h3Kuny3pwohNr4FxkbKuegjThsafBhYXCpH1o9oxjYMMxD-Tno8Iueh1c/s1600/image20130612_0002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTzc6eODCk4gdNlQTy6MY2LXr68l-xMkXnmiz74tNSig4e_NRBDj7yWyFTzMdz_jJKTL-o02bqI_cgyOnf8a-h3Kuny3pwohNr4FxkbKuegjThsafBhYXCpH1o9oxjYMMxD-Tno8Iueh1c/s320/image20130612_0002.jpg" width="180" /></a></div>
<div style="text-align: left;">
<span style="font-family: Arial, Helvetica, sans-serif;">If you work in a distributed environment, I highly recommend giving co-working a try. If you are working independently in Seattle, I strongly recommend you join Office Nomads.</span><span style="font-family: 'Times New Roman';"> </span></div>
</div>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-large;">Getting There</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG7U_Kw2IwBhZIPbqCWRN51xk23TM4aVykTwtU_zk1-lWjEzsp0KHTTmFNqBvvyC0MsjN2554-DhMH5y2KKrTPprAhS7YKuW40fTkE67keCx0zOePx8D2jAgxSarRWOzKEIcAqm3a9HaYx/s1600/image20130601_0003.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG7U_Kw2IwBhZIPbqCWRN51xk23TM4aVykTwtU_zk1-lWjEzsp0KHTTmFNqBvvyC0MsjN2554-DhMH5y2KKrTPprAhS7YKuW40fTkE67keCx0zOePx8D2jAgxSarRWOzKEIcAqm3a9HaYx/s320/image20130601_0003.jpg" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">It's been a very unreal sprint in Seattle. Reliably nice weather most days. So, since I am traveling to Office Nomads, I take my bicycle almost every day. This builds in free exercise for me, and is slightly faster than the bus. As a result, I have been biking more and more.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.blogography.com/photos14/KeepRight.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="http://www.blogography.com/photos14/KeepRight.gif" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">I flatter myself to think that I am relatively fit these days. None the less, I get passed by other bicyclists most days. When I get passed, I notice. I noticed that I have about three responses when this happens.</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Nice Bike! Often I am passed by much more serious bicyclists, and I notice their bikes costs many times what mine costs. However, this thought is really a small cop out. The fact is, they are all probably more fit and better at bicycling than I am, and generally invest more effort it in, that's why they are passing me. If we switched bikes, they'd still be faster than me.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Good for you! This is more typical. I can admire that the passer is more engaged, fitter, and just generally cares more about going fast at this point in time than I do. Someone going faster than me takes absolutely nothing away from my experience, and it's cool that they an do it.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Oops. Sometimes when I get passed I realize that my mind has wandered. I forgot to keep going fast. This is helpful. Realizing that I am daydreaming instead of focused on going fast, I can decide, to go fast, or maybe I decide I am happy day dreaming. In this way, someone passing me not only doesn't take anything from me, but it grants me something positive.</span></li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.autosavant.com/wp-content/uploads/2009/09/no-passing-zone.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://www.autosavant.com/wp-content/uploads/2009/09/no-passing-zone.jpg" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I pass more people than pass me, by a wide margin. Sometimes on longer, lonelier, rides, I observer other bicyclists as I pass them. The overwhelming majority of people I pass show essentially no response. They couldn't care less that I am passing them. Some folks even take advantage of the situation and draft behind me. They can go a little faster "for free" by letting my cut through the air for them.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">However, sometimes, I sense a certain amount of rage from people I pass. I can see it in their faces and body language. The fact that I am fitter and working harder takes nothing from these people, but it seems to bother them that someone can go faster than them. For this set of people, a common response is for them to work really hard to pass my back. This means that my presence was helpful for them if they want to go faster, but often, it's not sustainable for them, and I end up soon passing them again, and leaving them far behind. These folks end up with a self-inflicted net loss. They have a loss of pleasure, and they end up being driven by being passed, rather than being driven by what they want to do. A shame, really.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">As an aside, one time I was coming back from a very long ride, and took a break, going slowly for a few miles before my final push home. During this time, I heard someone pumping behind me. Finally, I was passed by someone clearly working to get back in shape. I was going the perfect speed for them, just fast enough that it was a challenge to pass me. As he passed, and I saw the look of pride mixed with exhaustion on his face, my heart went out to him. When it was time for me to go fast again, I quickly caught up with him, but then I fell behind. I just didn't have the heart to show him what going really fast looks like.</span><br />
<br />Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com21tag:blogger.com,1999:blog-7497847932106835950.post-23298247471774765392013-06-05T16:29:00.002-07:002013-06-05T16:29:39.750-07:00The Social Phone<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnKWF8im0S8cmdTWRgSLBiL4nKJNwWh_fVNznKHYOd87mvWsQGhxTYlxMCT4FsrmIenhLbgCGbXH4gejdj9g1ypVbyHLnFeUyTM85GxfyVTAbSCaT32YkFrJag2oOOX1_lYJZrEF-nkcJb/s1600/screenshot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnKWF8im0S8cmdTWRgSLBiL4nKJNwWh_fVNznKHYOd87mvWsQGhxTYlxMCT4FsrmIenhLbgCGbXH4gejdj9g1ypVbyHLnFeUyTM85GxfyVTAbSCaT32YkFrJag2oOOX1_lYJZrEF-nkcJb/s400/screenshot1.png" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Yesterday I blogged about how psyched I was to have cellular data on my phone. Then I listed some things that the Ubuntu Touch needed to reach parity with my old Android phone, for me, personally. One of those missing things was a way to share images from my phone. But look! This actually works already. It turns out that there is a good start of social integration already started and working. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Thanks to Bill Filler for walking me through the simple steps. Here's what to do if you want to get Twitter working.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Step 1: In your terminal, run the command $uoa-create twittter <your-twitter-username>. So for me, I did "uoa-create twitter rickspencer3".(to get Facebook integration use $uoa-create facebook <your-facebook-username>. </your-facebook-username></your-twitter-username></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBIsHcAHwsfyeZuy1LxODpPNZf1Memi4skNFys_-XfqIY3Gehr7M2z8MYm3oDBxtLgUyVU_sHwFA12O0tNEunVGQ2tLSOwd_SXotKwk1ZCC3kHfPF85C0UHBkvEfX5IWPPMImYgXoyLbBA/s1600/screenshot2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBIsHcAHwsfyeZuy1LxODpPNZf1Memi4skNFys_-XfqIY3Gehr7M2z8MYm3oDBxtLgUyVU_sHwFA12O0tNEunVGQ2tLSOwd_SXotKwk1ZCC3kHfPF85C0UHBkvEfX5IWPPMImYgXoyLbBA/s400/screenshot2.png" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Step 2: Wait for the Twitter auth web page to open. For some reason it is really tiny and you can't zoom it. The Facebook page is also tiny, but you can zoom it. However, be careful, the Facebook page requires you to click the commit button, which is way down on the bottom right. </div>
<div class="separator" style="clear: both; text-align: center;">
<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF91b9Mn9UrQs54ojNZbF1EGtpO71dU33YIfTe207tmBAhpgLiTcz4Z7zQOqHOtmCGiEI3B_A8TVfIBIKUVGZjmPoHueLm-31EzClS8lcB4ceG-5JHYfIURfNfW4DSzZGz63ai5-f9pXer/s1600/screenshot3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF91b9Mn9UrQs54ojNZbF1EGtpO71dU33YIfTe207tmBAhpgLiTcz4Z7zQOqHOtmCGiEI3B_A8TVfIBIKUVGZjmPoHueLm-31EzClS8lcB4ceG-5JHYfIURfNfW4DSzZGz63ai5-f9pXer/s400/screenshot3.png" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Step 3: Go to the Application lens. Search for the Friends app, and launch it.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiorCBiF-MBX55-SlwTO-9L-b6Q2mPXeJhHB8fSYrw3IkZRE7QI08p5y5-443J5QAMfxRjiLz95isuN6FMOXt_Xs8JUOlxXKTw8WVUsCz0W9rz0FSn8ozBH4BG3nc-79Zihu1DbgidIHwo/s1600/screenshot4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiorCBiF-MBX55-SlwTO-9L-b6Q2mPXeJhHB8fSYrw3IkZRE7QI08p5y5-443J5QAMfxRjiLz95isuN6FMOXt_Xs8JUOlxXKTw8WVUsCz0W9rz0FSn8ozBH4BG3nc-79Zihu1DbgidIHwo/s400/screenshot4.png" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Step 4: Glory in having your timeline on your phone!</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVocgs4yCKuPIXEpERyuvD2tMD_QbMkav4Sy02Rpc69K9_bM5bS5CxGTOhW4e0fxwH-uP4QtqBsxBefJio7xyP-WJXtMy5PLVDofombQZQC5WiNrsM8_3Oq5w6JSndl_2uFCRYgoSmGqzE/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVocgs4yCKuPIXEpERyuvD2tMD_QbMkav4Sy02Rpc69K9_bM5bS5CxGTOhW4e0fxwH-uP4QtqBsxBefJio7xyP-WJXtMy5PLVDofombQZQC5WiNrsM8_3Oq5w6JSndl_2uFCRYgoSmGqzE/s400/screenshot.png" width="240" /></a></div>
<br />
Note that only Twitter and Facebook are integrated so far, more networks coming soon. Also note that you can't tweet pics from your gallery yet, but that is coming soon as well.<br />
<br />
Of course, we can't rely on using a terminal to set up things like this. I'll be excited to see more social networks and a a GUI configurator land in the image.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com53tag:blogger.com,1999:blog-7497847932106835950.post-36643666083249241722013-06-04T17:54:00.002-07:002013-06-04T17:54:46.437-07:00Dog Fooding Success<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxpPJ1JBcszuAg4KY0dm4PvkDXqGlqkYdh8PzbwHUt_skVtZ3yROxuKJgZBEejJfFNKuxeyjS6aEsM6dw3O6xwWbzZMbli-AjHcIFYvwvzauN-3r3ILhQb2LuF4WFKa9Ba6VLdtqaVPs5M/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxpPJ1JBcszuAg4KY0dm4PvkDXqGlqkYdh8PzbwHUt_skVtZ3yROxuKJgZBEejJfFNKuxeyjS6aEsM6dw3O6xwWbzZMbli-AjHcIFYvwvzauN-3r3ILhQb2LuF4WFKa9Ba6VLdtqaVPs5M/s640/screenshot.png" width="384" /></a></div>
Last week I was in Washington DC house hunting (successfully, I might add ;) ). Since I abandoned my Android phone for full time Ubuntu Touch phone, the lack of cellular data was painful, but not as painful as I thought it would be because there was wireless everywhere. However, there were a couple of times that I would have liked to have checked email and such when I wasn't around wireless. Also, I get lost easily, so not being able to check a map was a painful regression once or twice.<br />
<br />
So, today, I was really happy to get the cellular data set up on my phone, and knock around Seattle a bit trying it out. It worked really well. It was interesting to see how so much of the slowness of my old phone was the phone itself, and not the cellular network speed as I had thought. I got a nice snappy experience on Ubuntu Touch.<br />
<br />
In the image above, you can see that one needs to use the terminal to turn the cellular data connection on and off. I wish we had co-developed the GUI with the backend support. I would like us to start thinking more across the team, seeing if we can bring experiences out in full. That said, I know it was a huge amount of work to get data working, and having the back end working and keeping it working is certainly a solid way to develop. So, great job to the Phonedations team!<br />
<br />
Having cellular data completes the "daily driver" goals we set! Never one to rest, now I am thinking about what would bring parity for my Ubuntu Touch phone in terms of the features that I actually used on my Android phone. The list is modest:<br />
<br />
<ol>
<li>My phone sometimes gets hot and then the batter runs down faster than it should. Would love to figure out what is going on there and get longer batter life.</li>
<li>Getting pictures *off* my phone. I can take pictures, but can't share them yet. </li>
<li>Loading up and watching videos. I like to take videos to the gym and on trips and watch them on my phone sometimes.</li>
<li><a href="http://en.wikipedia.org/wiki/Euchre">Euchre</a>. I know this is silly, but I have passed a lot of time playing this card game on my last phone. Maybe I can make my own implementation, but programming a card game seems like it would best be done with a framework, and it's not really up my ally.</li>
</ol>
<div>
I'm sure everyone has a different list like this, but I bet I am the only one with Euchre on their list. :)</div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com102tag:blogger.com,1999:blog-7497847932106835950.post-37867307982276398512013-05-24T15:37:00.001-07:002013-05-24T15:37:12.875-07:00all dogfood diet<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwmqCo2YvSRiPowc906xAzzubQbpSg4VNOmBozwWqA8jU07DiJGGzP00gEeQVbGwLk1O9SSScNber4lC3mzVKbiSeBC7kkukEcI9o7odQc6WuUE6B1hfHdglTa6c4POdFfNEVolGJFZxDr/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwmqCo2YvSRiPowc906xAzzubQbpSg4VNOmBozwWqA8jU07DiJGGzP00gEeQVbGwLk1O9SSScNber4lC3mzVKbiSeBC7kkukEcI9o7odQc6WuUE6B1hfHdglTa6c4POdFfNEVolGJFZxDr/s320/screenshot.png" width="192" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Yesterday I walked to my local t-mobile store and had them cut my SIM down to "micro" size. I did this so I could fit it into my Nexus 4. I wanted to put it into my Nexus because I decided that it was ready for me to start using full time. I put my Galaxy II away. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
I decided to do this because as of yesterday I could:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Import my contacts</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Make and receive SMSs</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Make and receive phone calls</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Use the internet via a wireless connection</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
It still lacks data over the cellular network. We won't get that until next week. So, I can't really say that it's dogfoodable for everyone as per our original goals, but we are close!</span>Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com37tag:blogger.com,1999:blog-7497847932106835950.post-24963195376677792352013-05-17T10:40:00.003-07:002013-05-17T11:07:44.937-07:00Dogfood Update<div class="separator" style="clear: both; text-align: center;">
<a href="https://pbs.twimg.com/media/BKfAh1ICEAAV7T-.jpg:large" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Arial, Helvetica, sans-serif;"><img border="0" height="320" src="https://pbs.twimg.com/media/BKfAh1ICEAAV7T-.jpg:large" width="240" /></span></a></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">At the end of April, we set the goal to have Ubuntu Touch be <a href="http://theravingrick.blogspot.com/2013/05/woof-woof.html">dogfoodable</a> on the Nexus and Nexus 4 phones. By that we mean, the goal is to make it so that we can use our phones exclusively as our phones. Today I chatted with some of the engineering managers involved to see how much progress we have made towards that. I am happy to say that it looks like we are still on track for this goal. However, there do appear to be some risky parts, so I am keeping my fingers crossed.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can make and receive phone calls: Done!</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can make and receive sms messages: Done!</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can browse the web on 3g data: Tony had been blocked on some technical issues, but thinks he's through them, so is in the debugging phase. He expects to have this done by end of May as per the dogfooding goal. For me, personally, this is the only missing part for me to be able to use the phone as my main phone around town. So, if Tony cracks this nut, then I will put away my old phone and start using my Ubuntu Phone exclusively.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can browse the web on wifi: Done! This has actually been done for quite a while.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can switch between wifi and 3g data: There are 2 parts to this work. There is low level networking code to get done, and then there is UI to enable it. That means that the Phone Foundations team and the Desktop team both have work to do. Both teams expect to get it done for May, but the work is not started yet.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The proximity sensore dims the screen when you lift the phone to talk on it: There are two parts to this also. Gather the sensor data and then making the phone app use the sensor data. Work has not started for this part either.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can import contacts from somewhere, and you can add and edit contacts: There is some work done on this that imports from a *.csv file. I expect there will be some crude support for this in time for the May goal. It might be fun for someone to try out a more elegant implementation. Ubuntu Phone is using Evolution Data Server for the contacts store, so there may be folks out there who already have the experience to do this easily.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">When you update your phone your user data is retained, even if updating with phablet-flash: Done! This part being done makes the contacts import less important to me because as I add contacts they won't get blown away. On the other hand, it means it is worth it to import contacts, since you won't have to re-important as you update your phone each day (while it is in development).</span></li>
</ul>
<br />
<div>
<br /></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com25tag:blogger.com,1999:blog-7497847932106835950.post-263486785856948672013-05-16T14:21:00.001-07:002013-05-16T14:21:17.507-07:00Feel Like Friday (post-vUDS)<br />
<span style="font-family: Arial, Helvetica, sans-serif;">It feels like Friday! Why? I think it's because I am tired. I am tired because Virtual UDS turns out to be surprisingly intense.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg27qWcvOWlu-DqWR0psV5MT4mNmixjQO1yr3GSYpEBFvyiJL1m8FzvvHwZcZJellYmrX7wxoGmB5EwdKtf-tok4apw7dAzyg5wY8BhfpovvPYXq8UBV3zOSoU7IIOsFLN2GIACw8GzRY8y/s1600/fist.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg27qWcvOWlu-DqWR0psV5MT4mNmixjQO1yr3GSYpEBFvyiJL1m8FzvvHwZcZJellYmrX7wxoGmB5EwdKtf-tok4apw7dAzyg5wY8BhfpovvPYXq8UBV3zOSoU7IIOsFLN2GIACw8GzRY8y/s1600/fist.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Power to People</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">So, that is to say, the second Virtual UDS is over. After experience my second vUDS, I think vUDS is really a boost for the transparency of the Ubuntu Project for a few reasons.</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><b>Frequency</b>. We can do it every 3 months instead of every 6 months. As I mentioned in the opening plenary, this is important because we don't actually plan only every 6 months anymore. Like any modern software project, we are continuously planning. The 3 month cadence for vUDS means that there will be less time between detecting a need to change plans and discussion about how to make those necessary changes. I pushed very hard to have the first vUDS quickly, because there was a lot of planning for Ubuntu Touch that was backed up and needed proper discussion. If we waited until now, a lot of the work would have started without a good opportunity for discussion.</span></li>
<li><b style="font-family: Arial, Helvetica, sans-serif;">Access</b><span style="font-family: Arial, Helvetica, sans-serif;">. Folks don't have to travel to wherever UDS is. People with specific interests can rock those interests with a laser focus, without having to dedicate a whole week away from home. Let's face it, traveling for 2 weeks a year to participate in UDS is something that only a few privileged people can swing. Many many more people can join a hangout.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><b>Persistence</b>. The sessions are streamed live, but then instantly available for reviewing, along with the white board, links to blueprints, etc... Try it. Go to <a href="http://summit.ubuntu.com/uds-1305/">Summit</a> for the UDS that just ended. Find a session. Click on the session. It's like you are there live. Discussions that used to exist only in the memories of a select few with some written traces are now persisted and available.</span></li>
</ul>
<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Personal Faves</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">I won't go into a run down of the results, because <a href="http://summit.ubuntu.com/uds-1305/meeting/21823/closing-plenary/">that job is taken</a>. However, here are some of my personal favorite discussions at this vUDS. These are my favorites based only on personal interests of mine. These are by no means the most important decisions or discussions. Just things that interest me a lot personally.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnnJeyx5Oqd4f-2uLDzhyphenhypheniXJO5QmRHVUgrxCStkWMxwEfeU-uEdUz_W4AayQLGXpHh8oPencsuGeKii8403-2HBo7DsuB_vBIzjI6FEoYwThgYXLscr_Oir6UuwxkYobN_WGGF3O1eE3A/s400/Wheeling+salamander.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnnJeyx5Oqd4f-2uLDzhyphenhypheniXJO5QmRHVUgrxCStkWMxwEfeU-uEdUz_W4AayQLGXpHh8oPencsuGeKii8403-2HBo7DsuB_vBIzjI6FEoYwThgYXLscr_Oir6UuwxkYobN_WGGF3O1eE3A/s320/Wheeling+salamander.jpg" width="249" /></a></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Rolling Release</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">After the unfortunate kerfufle last cycle when I pushed hard to move Ubuntu to a model of LTSs with rolling releases in between, it was niceto close in on one nice outcome. Namely, Colin has a technical solution that will allow users to subscribe to essentially the tip of development. Instead of using "raring" or "saucy" in your sources lists, you'll subscribe to a new name which is symlinked to whatever is the current development release. In this way, each day you will be on the latest. Even the day after a development release becomes a stable release, because the symlink will just point to the next development release.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I ended up with a couple of <a href="https://blueprints.launchpad.net/ubuntu/+spec/foundations-1305-development-release-planning">action items from this session</a>. Mostly, to come up with a name and bring it to the next Tech Board meeting for approval. I'm very much leaning to "rolling", but I am open to discussion ;) This would mean you could say "I am on Raring", or "I am on Precise", or "I am on Rolling". "I am on Rolling" means that you are on the tip of development. Fun!</span><br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Touch Image Testing</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">I've been very keen to get Ubuntu Touch out of "preview" mode and into our standard development processes so that they inherit all of the daily quality tools that we have in place. This means moving all the code of out PPAs and into the real archives, so that we get the benefits of all the efforts we have put into place around -proposed and archive maintenance. It also means getting smoke testing and regression testing automated on the Touch images. I loved hearing from the Phone Foundations team and the QA team about their vision for "not accepting regressions". We should have dog-foodable touch images as early as the end of this month. Then if we can keep the images fully usable with minimal regressions each day, we will go very fast towards completion.</span><br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Ubuntu Status Stracker</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">I am partial to this topic because the status tracker started out as a labor of love for me. The first real <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/py-burndown-chart/view/head:/burndown.py">bit of code</a> that I wrote after joining canonical was to render my version of burndown charts. If I am not mistaken this code is still in use. In any case, <a href="http://status.ubuntu.com/ubuntu-s/">status.ubuntu.com</a> is critical to maintaining our planning, and ensuring that the status of the project is visible to all.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Unity 8 in 13.10</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">While 13.10 is very very focused on Ubunty Touch for phones, we all know that the real prize is the fully converged client OS. With that in mind, I think it's important to get the code up on as many device types as possible as soon as possible. There was a rich discussion about the steps to offer Unity 8 on top of Mir as an option in 13.10. Now, keep in mind that the result will only be the Phone UI on the desktop, and the default will be the Unity that we know and love today (with Smart Scopes and other enhancements of course!). Still in all, I am betting that basing Unity 8 on QML means that it will be surprisingly functional on a desktop even though it won't have any real desktop support in terms of things like workspace switching, etc..</span><br />
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com18tag:blogger.com,1999:blog-7497847932106835950.post-91458696619053454402013-05-13T16:54:00.001-07:002013-05-13T17:00:47.264-07:00A little bit of reusable code Sound Button<span style="font-family: Arial, Helvetica, sans-serif;">Want a button for Ubuntu Components that plays a sound when pressed, and stops when released? Here's SoundButton . Perfect for your typical Sound Board type app.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<pre><!--StartFragment--><span style="color: olive;">import</span><span style="color: silver;"> </span>QtQuick<span style="color: silver;"> </span>2.0</pre>
<pre><span style="color: olive;">import</span><span style="color: silver;"> </span>Ubuntu.Components<span style="color: silver;"> </span>0.1</pre>
<pre><span style="color: olive;">import</span><span style="color: silver;"> </span>QtMultimedia<span style="color: silver;"> </span>5.0</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">Button</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">id</span>:<span style="color: silver;"> </span><span style="font-style: italic;">soundButton</span></pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">property</span><span style="color: silver;"> </span><span style="color: olive;">string</span><span style="color: silver;"> </span><span style="color: maroon;">soundUrl</span>:<span style="color: silver;"> </span><span style="color: green;">""</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">onPressedChanged</span>:</pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">if</span>(<span style="font-style: italic;">pressed</span>)</pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="font-style: italic;">audio</span>.play()</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">else</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="font-style: italic;">audio</span>.stop()</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">Audio</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">id</span>:<span style="color: silver;"> </span><span style="font-style: italic;">audio</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">source</span>:<span style="font-style: italic;">soundButton</span>.soundUrl;</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre>}<!--EndFragment--></pre>
<pre></pre>
<pre></pre>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com28tag:blogger.com,1999:blog-7497847932106835950.post-62707100990367309292013-05-08T13:36:00.002-07:002013-05-08T13:36:49.995-07:00Woof woof!<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://cappers.grit.com/uploadedImages/CAP/articles/issues/2009-05-01/Homemade-dog-food-Web.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://cappers.grit.com/uploadedImages/CAP/articles/issues/2009-05-01/Homemade-dog-food-Web.jpg" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Last week I fell into a discussion with Mark, Pat, and others about the importance of being able to <i>really</i> use a piece of software to really know how far there is between where you are, and a shippable state. Of everything that is missing, it's hard to know what is really the most important unless you can really use it and find what you have to work around, versus what you can just do without.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Out of this conversation was born the idea that we should drive as hard as we can to making it so that we can use our phones with Ubuntu Touch as our real daily phones as soon as possible. Really eat our own dogfood, so to speak. woof!</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">So, we committed our teams to making it so that by end of May, the phone images will be usable as our daily phones, defined as the following:</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can make and receive phone calls</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can make and receive sms messages</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can browse the web on 3g data</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can browse the web on wifi</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can switch between wifi and 3g data</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The proximity sensore dims the screen when you lift the phone to talk on it</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can import contacts from somewhere, and you can add and edit contacts</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">When you update your phone your user data is retained, even if updating with phablet-flash</span></li>
</ul>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">We believe that at least some of us will be able to really dogfood if we accomplish that. Of course, there will be a lot missing. Off the bat, I can thinking of things like the ability to find and install new apps, hardware not working on certain reference hardware (camera on Nexus 7 for example?), lots of missing features in existing apps, etc... However, in my experience, progress accelerates when people are using, in addition to building, software.</span><br />
<div>
<br /></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com481tag:blogger.com,1999:blog-7497847932106835950.post-405620672664512642013-05-07T10:33:00.002-07:002013-05-08T13:34:12.707-07:00Ugly Duckling to Beautiful Swan, or How an App Developer Benefits from Designer/Developer Collaboration<br />
Last week I snatched an hour here and there to work on my <a href="http://feedzilla.com/api-overview">Feedzilla</a> app. I like Feedzilla because it has an api that is free for me to use, so it's easy to write the app. However, I'm not totally enamored with the content, it seems like it is often out of date, though I suppose I can apply a filter to limit the content to new stuff from this week, or whatever.<br />
<br />
However, what really stopped me working on it was that my implementation was just depressingly ugly. I'd look at all the <a href="http://design.canonical.com/2013/04/core-utility-apps-visual-exploration/">cool and beautiful things</a> that other people were doing with their apps, and be totally unmotivated to work on TechNews. Last week, I decided to ask for some help in how to improve my app, and I was told about <a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/overview-ubuntu-sdk.html#list-items">ListItems</a>. For TechNews, it was like the sun coming out from behind the clouds.<br />
<br />
Now, the thing abut Ubuntu.Components is that the project is fundamentally a design project. Yes, the components need, and have, an awesome development team that makes them "real", but the components are really about providing developers with the tools for making a well designed "Ubuntu App". This couldn't be more clear than when using ListItems.<br />
<br />
For an example, to turn the categories list from this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQyaCGGNF2nHYgjYPpBf3AeutFjtCRVPbvM5nbjjiqthFfC_ZOlqV0tQITHEGEdWFFpdpN7XLTHBr-6UmTlX02ob5vjFSgRBpt40CBpoqVRj-HxmvSuWZyxHo4hyD4YxZTd614P93ZTou9/s1600/screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQyaCGGNF2nHYgjYPpBf3AeutFjtCRVPbvM5nbjjiqthFfC_ZOlqV0tQITHEGEdWFFpdpN7XLTHBr-6UmTlX02ob5vjFSgRBpt40CBpoqVRj-HxmvSuWZyxHo4hyD4YxZTd614P93ZTou9/s320/screenshot.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My very ugly list which was my honest best effort without design help.</td></tr>
</tbody></table>
<br />
to this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhktoK7EXHrAELeZxg0xJsJdHULP-3QH_Jl4Gfpfxatmu8UaD35UKamrOa9y1zyrWkhoxbKE1Jhoxi3TqW4n2ik7I7cXmVN5PV2fG7y9zFV8XYSAZDf6k6hi-zQcBeZI3cxy-17_0nFGJJl/s1600/Screenshot+from+2013-05-07+10:25:06.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhktoK7EXHrAELeZxg0xJsJdHULP-3QH_Jl4Gfpfxatmu8UaD35UKamrOa9y1zyrWkhoxbKE1Jhoxi3TqW4n2ik7I7cXmVN5PV2fG7y9zFV8XYSAZDf6k6hi-zQcBeZI3cxy-17_0nFGJJl/s320/Screenshot+from+2013-05-07+10:25:06.png" width="257" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My now lovely list that I got to be that way just by using the right components and inheriting all of the designers' knowledge and talents.</td></tr>
</tbody></table>
<br />
I just had to use Standard list items. First, I went ahead and imported the ListItem namespace:<br />
<pre><span style="color: olive;">import</span><span style="color: silver;"> </span>Ubuntu.Components.ListItems<span style="color: silver;"> </span>0.1<!--EndFragment--></pre>
<br />
Then this is what my delegate for each list item looks like. The "progression: true" declares that the item will navigate somewhere. The designers ensured that this means the list item adds that ">", so it is standard navigation in all apps!<br />
<pre><!--StartFragment--><span style="color: silver;"> </span><span style="color: maroon;">delegate</span>:<span style="color: silver;"> </span><span style="color: purple;">Standard</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">progression</span>:<span style="color: silver;"> </span>true;</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">text</span>:<span style="color: silver;"> </span><span style="font-style: italic;">articlesListView</span>.model[index][<span style="color: green;">"title"</span>]</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">onClicked</span>:</pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="font-style: italic;">articleSelected</span>(<span style="font-style: italic;">articlesListView</span>.model[index][<span style="color: green;">"url"</span>])</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><!--EndFragment--></pre>
<br />
<div>
So my app went from ugly duckling to beautiful swan just by using the right components and getting all the benefit of the designers' abilities that I so sorely lack. Thanks SDK team!</div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com26tag:blogger.com,1999:blog-7497847932106835950.post-82810596861821934092013-04-15T17:46:00.003-07:002013-04-15T18:02:55.298-07:00FingerPaint, my 20 minute app<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLOIwO9WlyLq4aZQRbKgYwKYmqk98MSLt9neQe3NAoX4nCy6rupZPkRSsQG6f9NAoqG3YtjcbhUlve7-T4d2kaC0CdHwcKZ6QKbqcmbkABv8lDUb7Vbhy1K0b22QaAcv9Vgu3Jjh1b11Sg/s1600/Screenshot+from+2013-04-15+17:37:28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLOIwO9WlyLq4aZQRbKgYwKYmqk98MSLt9neQe3NAoX4nCy6rupZPkRSsQG6f9NAoqG3YtjcbhUlve7-T4d2kaC0CdHwcKZ6QKbqcmbkABv8lDUb7Vbhy1K0b22QaAcv9Vgu3Jjh1b11Sg/s320/Screenshot+from+2013-04-15+17:37:28.png" width="320" /></a></div>
Here's a quick demo of using InkCanvas.<br />
<br />
First I create a rectangle to fill the window to make everything white. Then I made an InkCanvas and set the InkWidth to something like a kid would finger paint:<br />
<pre><!--StartFragment--><span style="color: silver;"> </span><span style="color: purple;">InkCanvas</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">id</span>:<span style="color: silver;"> </span><span style="font-style: italic;">inkCanvas</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">width</span>:<span style="font-style: italic;">parent</span>.width</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">height</span>:<span style="font-style: italic;">parent</span>.height<span style="color: silver;"> </span>-<span style="color: silver;"> </span><span style="font-style: italic;">paintPotSize</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">inkWidth</span>:<span style="color: silver;"> </span>30</pre>
<pre><span style="color: silver;"> </span>}<!--EndFragment--></pre>
<br />
<br />
So, now that I have an InkCanvas component, the inking is the easy part. I spent most of the 20 minutes working on the paint color selector.<br />
<br />
Those blocks along the bottom are MouseAreas filled with UbuntuShapes. So I just respond to the clicked signal and set the InkCanvas's inkColor property ...<br />
<br />
Using a Repeater, I can set them up like this:<br />
<pre><!--StartFragment--><span style="color: silver;"> </span><span style="color: purple;">Row</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">width</span>:<span style="color: silver;"> </span><span style="font-style: italic;">parent</span>.width</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">height</span>:<span style="color: silver;"> </span><span style="font-style: italic;">paintPotSize</span></pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">Repeater</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">model</span>:<span style="color: silver;"> </span>[<span style="color: #0055af; font-style: italic;">Qt</span>.rgba(1,0,0,.5),<span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(0,1,0,.5),<span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(0,0,1,.5),</pre>
<pre><span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(1,1,0,.5),<span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(1,0,1,.5),<span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(0,1,1,.5)]</pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">MouseArea</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">height</span>:<span style="color: silver;"> </span><span style="font-style: italic;">paintPotSize</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">width</span>:<span style="color: silver;"> </span><span style="font-style: italic;">paintPotSize</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">onClicked</span>:<span style="color: silver;"> </span>{<span style="font-style: italic;">inkCanvas</span>.inkColor<span style="color: silver;"> </span>=<span style="color: silver;"> </span>modelData}</pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">UbuntuShape</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">anchors.fill</span>:<span style="color: silver;"> </span><span style="font-style: italic;">parent</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">color</span>:<span style="color: silver;"> </span>modelData</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span>}</pre>
<br />
Tada ... a finger paint program suitable for kids to get their grubby mits all over your device in 20 minutes :)<br />
<br />
<a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/FingerPaint/files">Code is here</a>Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com9tag:blogger.com,1999:blog-7497847932106835950.post-8831617062014055072013-04-15T16:57:00.001-07:002013-04-15T16:57:21.469-07:00Introducing InkCanvas<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigX-f1EHMw3om-YFHa2upkvtBlBTcM0fQPZqI92v-WBrC_eIQUV_omZjC9pBnyeGSOq9PGDU3jYiDOqjqir5y5VpQB79z2YDjvUc1pPXyNSm9RQp6HF54wpj1aRCTqY8HRJas95EjBQBhd/s1600/Screenshot+from+2013-04-15+16:40:13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigX-f1EHMw3om-YFHa2upkvtBlBTcM0fQPZqI92v-WBrC_eIQUV_omZjC9pBnyeGSOq9PGDU3jYiDOqjqir5y5VpQB79z2YDjvUc1pPXyNSm9RQp6HF54wpj1aRCTqY8HRJas95EjBQBhd/s320/Screenshot+from+2013-04-15+16:40:13.png" width="320" /></a></div>
So, I drew a beard on Tard today! Furthermore, I did it with just a few lines of QML. Here's the whole program for drawing on Tard ...<br />
<br />
<pre><!--StartFragment--><span style="color: purple;">MainView</span><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">objectName</span><span style="color: silver;"> </span><span style="color: green;">for</span><span style="color: silver;"> </span><span style="color: green;">functional</span><span style="color: silver;"> </span><span style="color: green;">testing</span><span style="color: silver;"> </span><span style="color: green;">purposes</span><span style="color: silver;"> </span><span style="color: green;">(autopilot-qt5)</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">objectName</span>:<span style="color: silver;"> </span><span style="color: green;">"mainView"</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">applicationName</span>:<span style="color: silver;"> </span><span style="color: green;">"InkArea"</span></pre>
<pre><span style="color: silver;"> </span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">width</span>:<span style="color: silver;"> </span>units.gu(100)</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">height</span>:<span style="color: silver;"> </span>units.gu(75)</pre>
<pre>
</pre>
<pre>
</pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">Image</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">source</span>:<span style="color: silver;"> </span><span style="color: green;">"grumpycat.jpg"</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">anchors.fill</span>:<span style="color: silver;"> </span><span style="font-style: italic;">parent</span>;</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">fillMode</span>:<span style="color: silver;"> </span><span style="color: purple;">Image</span>.PreserveAspectFit</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre>
</pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">InkCanvas</span></pre>
<pre><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">anchors.fill</span>:<span style="color: silver;"> </span><span style="font-style: italic;">parent</span></pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">inkColor</span>:<span style="color: silver;"> </span><span style="color: #0055af; font-style: italic;">Qt</span>.rgba(0,<span style="color: silver;"> </span>0,<span style="color: silver;"> </span>0)</pre>
<pre><span style="color: silver;"> </span><span style="color: maroon;">inkWidth</span>:<span style="color: silver;"> </span>15</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre>}<!--EndFragment--></pre>
<pre>
</pre>
I just added an InkCanvas to my MainView and covered the Image with it. Simple, right? Well, you may have guessed there is slightly more to it than that. Where did InkCanvas come from? InkCanvas is a custom component that I wrote in <b>pure QML</b> to allow users to draw an a surface.<br />
<br />
You may be aware of my long interest in free from editing applications. Remember <a href="http://theravingrick.blogspot.com/search/label/photobomb">Photobomb</a>?<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_UJB7DcFDh9Hgib6UCyw9UAbs3iVayfWaGlqLUNlGvG9lxXQk3YMAQrplvPFUUmwoT_VKVpS_j7zuPSZRpk6DLrAr4WgrHGTRps7VAMjN7cJprnBsM2-7C3zRsqr6uTmR08cR35ivQM52/s1600/Screenshot-Photobomb-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_UJB7DcFDh9Hgib6UCyw9UAbs3iVayfWaGlqLUNlGvG9lxXQk3YMAQrplvPFUUmwoT_VKVpS_j7zuPSZRpk6DLrAr4WgrHGTRps7VAMjN7cJprnBsM2-7C3zRsqr6uTmR08cR35ivQM52/s320/Screenshot-Photobomb-2.png" width="320" /></a></div>
So, I decided to try my hand at collecting Ink in QML. There was some surprising complexity in getting it to work and work quickly, and it is still very much a work in progress. None the less, I want to invite people to:<br />
<br />
<ul>
<li>Download and use <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/InkCanvas/view/head:/InkCanvas.qml">InkCanvas</a> in their apps if they want. I hope it unlocks some fun things for people to do.</li>
<li>Contribute to making InkCanvas better. Extend it, fix it, break it, etc...</li>
</ul>
<br />
Note that it currently doesn't work perfectly on my Nexus7. Something seems to break the canvas when Ink starts getting drawn :(<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFzG7OAc2Ak716XCAPu56tzdOeM5Lfg-w_i3NeiAd2iz1d2IuhteksyntwvFZMewTEgz6Tem3o9Pj0z6mbNGq2ooaWbkTxvmCgV7OQ2UlG2duyLn0jzIl48tWHgcf16EDs3ZZQjLagzYp2/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFzG7OAc2Ak716XCAPu56tzdOeM5Lfg-w_i3NeiAd2iz1d2IuhteksyntwvFZMewTEgz6Tem3o9Pj0z6mbNGq2ooaWbkTxvmCgV7OQ2UlG2duyLn0jzIl48tWHgcf16EDs3ZZQjLagzYp2/s320/screenshot.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://bugs.launchpad.net/touch-preview-images/+bug/1168193">I logged a bug about this</a>, but for all I know, it has something to do with the way I am abusing the Canvas and Stroke Components. Though it does work fine on my desktop.</div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com9tag:blogger.com,1999:blog-7497847932106835950.post-31781042322284758572013-04-15T15:24:00.002-07:002013-04-15T15:25:58.617-07:00Easy Task Navigation With PageStack (Fixed)<br />
Thanks to an update to the <a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/qml-ubuntu-components0-pagestack.html">documentation for Ubuntu Components</a>, I discovered that I was using PageStack all wrong. I've gone ahead and deleted my old blog post about PageStack, and now here is a corrected one.<br />
<br />
My Feedzilla app has a very simply page by page structure. Each bit of UI that the user interacts with is a wholly separate task so can take over the whole screen to present to the user.<br />
<br />
Turns out, that Ubuntu Components have a component to support this in a standard, and very convenient, manner. It's called PageStack.<br />
<br />
Here's how it works.<br />
<br />
First, I created a PageStack component, and named it "rootStack". The categories view is always the starting point of the app, so I made it a Page inside the PageStack, and named it "rootPage". Then I added SubCategoriesPage (which is a ListView that shows the list of Technology sub-categories from Feedzilla:<br />
<br />
It looks like this.<br />
PageStack<br />
{<br />
id: rootStack<br />
Page<br />
{<br />
title: "Categories"<br />
id: rootPage<br />
SubCategoriesComponent<br />
{<br />
id: subCategoriesComponent<br />
anchors.fill: parent<br />
}<br />
}<br />
}<br />
<br />
Now, even though rootPage is visible, it's not actually on the PageStack yet. PageStack is a "stack" in the programming sense. That means you can push items on top of the stack, and pop items off. So I need to write some code to push rootPage onto the PageStack. I do this by adding an onCompleted handler to the PageStack and pushing the rootPage onto the PageStack there.<br />
<br />
PageStack<br />
{<br />
id: rootStack<br />
Page<br />
{<br />
title: "Categories"<br />
id: rootPage<br />
SubCategoriesComponent<br />
{<br />
id: subCategoriesComponent<br />
anchors.fill: parent<br />
}<br />
}<br />
Component.onCompleted:<br />
{<br />
push(rootPage)<br />
}<br />
}<br />
<br />
So, how does the user navigate? I added a signal to SubCategoriesComponent for when the user has selected a category.<br />
<br />
I made two other Components. One for displaying a list of articles and one for displaying articles themselves. I host these components inside of pages. I also set the pages to be invisible.<br />
<br />
<br />
Page<br />
{<br />
visible: false<br />
id: articlesListPage;<br />
ArticlesListComponent<br />
{<br />
id: articlesList<br />
anchors.fill: parent;<br />
onArticleSelected:<br />
{<br />
articleComponent.url = url<br />
rootStack.push(articlePage)<br />
}<br />
onTitleChanged:<br />
{<br />
articlesListPage.title = articlesList.title<br />
}<br />
}<br />
}<br />
Page<br />
{<br />
visible: false<br />
id: articlePage<br />
ArticleComponent {<br />
id: articleComponent<br />
anchors.fill: parent;<br />
}<br />
}<br />
<br />
When the user selects a category, they need to see a list of articles. I made ArticlesListComponent todo that job. When they select a specific article, the user should see the article, I created ArticleComponent for that. Note:<br />
<br />
So, getting back to the story, how do we push these onto the PageStack?<br />
<br />
Page<br />
{<br />
title: "Categories"<br />
id: rootPage<br />
SubCategoriesComponent<br />
{<br />
id: subCategoriesComponent<br />
anchors.fill: parent<br />
onSubCategorySelected:<br />
{<br />
articlesList.subCategoryId = subCategoryId;<br />
rootStack.push(articlesListPage)<br />
}<br />
}<br />
}<br />
<br />
You may recall that I added a onSubCategorySelected signal to my SubCategoriesComponent component. All I have to do is respond to that signal. First I configure my ArticlesListPage to use the sunCategoryId passed into the signal handler. Then I tell the PageStack to push articlesListPage (the instance of ArticlesListPage declared in the QML above). Pushing 'pushes' pushes the component on top of the categories list.<br />
<br />
I use similar code to push the ArticlesComponent when the user selects an article.<br />
onArticleSelected:<br />
{<br />
articleComponent.url = url<br />
rootStack.push(articlePage)<br />
}<br />
<br />
The ArticleComponent can only be on top, so it doesn't push anything.<br />
<br />
But what about going back? That's where popping comes in. I added an action to rootPage which simply tells rootStack to pop. Pop is opposite of push. Instead of adding something to the top of the stack, it takes whatever is on top off. It pops off the top. rootPage can't be popped off, though, because it is at the root. This makes the code easy. If I wanted to, I could handle popping myself with code like this:<br />
tools: ToolbarActions<br />
{<br />
Action<br />
{<br />
id: backAction<br />
text: "Back"<br />
iconSource: "back.png"<br />
onTriggered:<br />
{<br />
rootStack.pop();<br />
}<br />
}<br />
}<br />
<br />
<br />
However, this is not necessary because PageStack automatically creates and maintains a back button for me!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1rVUZ9iXlIEGAcEaDZQ6gj6XTtjdXGen9vDu4dIrgpelH26VUjadrRr2_Qk1Tp5zUYLaD7QGhlCa45W-41_FtwPEHoUSC0MgZqTRmNlqhEZdn7DIREs-KwAPgtB8YWGuVQcsOTFyBjjaH/s1600/Screenshot+from+2013-04-15+15:22:12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1rVUZ9iXlIEGAcEaDZQ6gj6XTtjdXGen9vDu4dIrgpelH26VUjadrRr2_Qk1Tp5zUYLaD7QGhlCa45W-41_FtwPEHoUSC0MgZqTRmNlqhEZdn7DIREs-KwAPgtB8YWGuVQcsOTFyBjjaH/s320/Screenshot+from+2013-04-15+15:22:12.png" width="320" /></a></div>
<br />
I pushed a <a href="https://code.launchpad.net/~rick-rickspencer3/+junk/technews">branch with my corrected code</a>.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com19tag:blogger.com,1999:blog-7497847932106835950.post-54533756973809856672013-04-02T16:56:00.002-07:002013-04-02T16:58:11.980-07:00ListView with JSON model (and the world's ugliest application)<br />
First, I want to extend my deepest apologies for how ugly this app is at the moment. It's embarrassing. Sorry. I will put lipstick on it later, I hope.<br />
<br />
This app is for browsing technical news from <a href="http://code.google.com/p/feedzilla-api/">Feedzilla</a>. It has 3 pages, A page for categories (well, subcategories because Tech is itself a category in Feedzill), a list of articles, and WebView to display an article.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg38SplDaacjnndYgUa6-vpP_UQHOc8eElj9zyemNEFvxxK7J8s6SxX4rdVL4GS-Z2Eo3OZKPYk3R1d29EqQYB6HK30GbmTIR7-ScjZfbVqsKhEoCN7hr9L7Q3EsIojyux_Ea2NrlOShnbo/s1600/screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg38SplDaacjnndYgUa6-vpP_UQHOc8eElj9zyemNEFvxxK7J8s6SxX4rdVL4GS-Z2Eo3OZKPYk3R1d29EqQYB6HK30GbmTIR7-ScjZfbVqsKhEoCN7hr9L7Q3EsIojyux_Ea2NrlOShnbo/s320/screenshot.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Main Category View</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1xh6-fYrCzWsy4lItG6UTO6ZegB93kydzLD863y3aD1YuN4WkfsMhdg8LcIGaIkTZ_koatZcZQVvEs9iOnyp6KgaFrRYyXJgZ9585CAK2KDmJLdy-kPXBJ3CQuseLJY0fh4tqH6SJl_m/s1600/screenshot2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1xh6-fYrCzWsy4lItG6UTO6ZegB93kydzLD863y3aD1YuN4WkfsMhdg8LcIGaIkTZ_koatZcZQVvEs9iOnyp6KgaFrRYyXJgZ9585CAK2KDmJLdy-kPXBJ3CQuseLJY0fh4tqH6SJl_m/s320/screenshot2.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Article List View</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjelbqsPWdnww0OE5u_kqIPFNpGZ3JfBpqUDM7Laykp_DuFjX9aJwhcRUzZYRd0IwIlpPM7QWMTF3Xdqc2bODlF33gm_0LsuYQFai7tzOQhZ5Rgi4Cie5pftZUHi4JHhOnOZcDuyd_OEPOf/s1600/screenshot3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjelbqsPWdnww0OE5u_kqIPFNpGZ3JfBpqUDM7Laykp_DuFjX9aJwhcRUzZYRd0IwIlpPM7QWMTF3Xdqc2bODlF33gm_0LsuYQFai7tzOQhZ5Rgi4Cie5pftZUHi4JHhOnOZcDuyd_OEPOf/s320/screenshot3.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Reading an Article in Embedded Webkit</td></tr>
</tbody></table>
<br />
However, I did want to blog about part of how I built it, because I think it is generally useful for folks to see how I made my ListViews from JSON.<br />
<br />
I blogged before about how I used an XmlListModel to make a ListView, and how easy that was. However, for this App, I wanted to use a JSON feed from feedzilla. However, there is no JsonListView. So what did I do? Here's how I made the main category view.<br />
<br />
To get started, I created a ListView, as usual:<br />
ListView<br />
{<br />
id: categoriesList<br />
anchors.fill: parent;<br />
}<br />
<br />
It doesn't do anything yet, because there is no model set. Remember, a ListView's only purpose in life is to display data in a list format. The data that I want is available in JSON format, so, next I need to get the JSON and set the model of the ListView.<br />
<br />
So, in onComplete method, I wrote some good old fashioned Ajaxy javascript.<br />
Component.onCompleted:<br />
{<br />
//create a request and tell it where the json that I want is<br />
var req = new XMLHttpRequest();<br />
var location = "http://api.feedzilla.com/v1/categories/30/subcategories.json"<br />
<br />
//tell the request to go ahead and get the json<br />
req.open("GET", location, true);<br />
req.send(null);<br />
<br />
//wait until the readyState is 4, which means the json is ready<br />
req.onreadystatechange = function()<br />
{<br />
if (req.readyState == 4)<br />
{<br />
//turn the text in a javascript object while setting the ListView's model to it<br />
categoriesList.model = JSON.parse(req.responseText)<br />
}<br />
};<br />
}<br />
<br />
The key line is the one that sets the ListView's model to a javascript object:<br />
categoriesList.model = JSON.parse(req.responseText)<br />
<br />
This works because all of the javascript that is returned is a list. So, I fetched a list in Javascript Object Notation, parsed it, and used it as a model for a ListView. Easy, right?<br />
<br />
So now that the ListView has a model, I can create a delegate. Remember, a delegate is a bit of code, like an anonymous method, that gets called for each element in the ListViews model, and creates a component for it. Whenever the model for the ListView changes, the delegate is called for each item in the model. Every time the delegate is called, it gets passed "index" which is the index of the current item being created. So the delegate uses that to get the correct element from the list of javascript objects.<br />
<br />
ListView<br />
{<br />
id: categoriesList<br />
anchors.fill: parent;<br />
delegate: Button<br />
{<br />
width: parent.width<br />
text: categoriesList.model[index]["display_subcategory_name"];<br />
onClicked:<br />
{<br />
subCategorySelected(categoriesList.model[index]["subcategory_id"])<br />
}<br />
}<br />
}<br />
<br />
My ListView is just a row of buttons, and the text is defined as "display_subcategory_name" in the JSON that I got from the server. So I can index in and set the text like so:<br />
text: categoriesList.model[index]["display_subcategory_name"];<br />
<br />
Bonus snippet! The code that I wrote is a component that gets used in a PageStack. I don't want the PageStack to have to know about how the category list is implemented, of course, so I want my component to emit a signal when when of the categories is selected by the user (which is by clicking a button in this implementation).<br />
<br />
Adding signals to a component is <b>really</b> easy in QML. First, you declare the signal where you declare properties and such for your component:<br />
signal subCategorySelected(int subCategoryId);<br />
<br />
In this case, the signal has a single parameter. A signal can as many parameters as you want.<br />
<br />
Then, the onClicked function for each button "fires" the signal by calling it like a function:<br />
subCategorySelected(categoriesList.model[index]["subcategory_id"])<br />
<br />
That means my PageStack can just listen for that signal:<br />
<br />
onSubCategorySelected:<br />
{<br />
//do stuff with subCategoryId<br />
}<br />
That's all you have to know to simplify your code with custom signals!Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com11tag:blogger.com,1999:blog-7497847932106835950.post-79613153103632955972013-03-28T17:39:00.002-07:002013-03-28T17:39:41.604-07:00User Interaction with Ubuntu Components<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsX7Nkfgc4kJm455eKpQ7TRsOQQ74cG8c_dcMzGmcbOh484nxiZjcflHM8nZj62zWg351_-yQqQobtHHaIy40_mnGsAyR37yUW0cN-qXIjIPNAPV5qpIHhZDKYn05u0x5CQepMFD2RkwE/s1600/screenshot3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsX7Nkfgc4kJm455eKpQ7TRsOQQ74cG8c_dcMzGmcbOh484nxiZjcflHM8nZj62zWg351_-yQqQobtHHaIy40_mnGsAyR37yUW0cN-qXIjIPNAPV5qpIHhZDKYn05u0x5CQepMFD2RkwE/s320/screenshot3.png" width="200" /></a></div>
<br />
I am so very able to amuse myself with all these funny pictures, but there are other amusing subreddits other than funny. So today I added the ability to choose a different subreddit. This involved diving into the world of <a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/overview-ubuntu-sdk.html">Ubuntu Components</a>.<br />
<br />
Ubuntu Components were surprisingly functional, but as you will see, they are still a work in progress.<br />
<br />
So, the first thing I needed to do was to make a way for the user to say that they want to change subreddits. Ubuntu Touch provides the bottom edge for your application to add a list of commands. This is a nice way to do it because it means that the screen isn't cluttered with commands, but users know exactly where to go when they want them.<br />
<br />
The first thing to do is to ensure that the top level of your app is a <a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/qml-ubuntu-components0-mainview.html">MainView</a>, and then you are presenting the content in a Page. So, roughly your apps structure looks like ...<br />
<br />
//imports<br />
MainView<br />
{<br />
//set MainView properties<br />
<a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/qml-ubuntu-components0-page.html">Page</a><br />
{<br />
//app UI content<br />
}<br />
//components outside pages<br />
}<br />
<br />
I wanted to add a "subreddit" button. To do that, I set the tools property of the page to a list of actions. So far there is only one action. Essentially, I am defining a button. I tell it the text I want, the icon to use (I downloaded an icon that I wanted) and the action to take. So this goes inside the Page tag:<br />
<br />
tools: ToolbarActions<br />
{<br />
Action<br />
{<br />
text: "SubReddit"<br />
iconSource: Qt.resolvedUrl("reddit.png")<br />
onTriggered: PopupUtils.open(subRedditSheet)<br />
}<br />
}<br />
Now you can see that if swipe from the button, I get my button.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsh7Zynt4iUm3n83jeNx48L5U9rALCAdRcxJlCtX-vhXXFHr4RU9OtnV4x5zg28KEjq9hSwB0SDEfufmhsPN13RftK9_UzUFEu8s4fcLkM3bkTIlChyL2h-3dy7FkF6K-WLIo5nItjRDj0/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsh7Zynt4iUm3n83jeNx48L5U9rALCAdRcxJlCtX-vhXXFHr4RU9OtnV4x5zg28KEjq9hSwB0SDEfufmhsPN13RftK9_UzUFEu8s4fcLkM3bkTIlChyL2h-3dy7FkF6K-WLIo5nItjRDj0/s320/screenshot.png" width="200" /></a></div>
But what is that action? What I did was create a <a href="http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/qml-ubuntu-components-popups0-composersheet.html">ComposerSheet</a> that allows the user to input the reddit that they want. You do this by defining a Component that wraps a ComposerSheet. A ComponentSheet is kind of like a dialog box. It handles putting Ok and Cancel buttons on for you. Note that you have to name the ComposerSheet "sheet", or you get errors. All I added was a TextField that I called "subRedditText, but you can fill the ComposerSheet with whatever you want.<br />
<br />
I just have to tell it what to do when the user clicks Ok. I did a little refactoring from yesterday to create a "changeSubReddit function that gets called on start up, and can get called from here. I just pass it the subreddit. (Don't forget to import Ubuntu.Components.Popups 0.1 in order to use the ComposerSheet).<br />
<br />
Then you call PopupUtils.open to pop it open when you want it (which I specify as the action for my reddit button in the ActionList).<br />
<br />
Component<br />
{<br />
id: subRedditSheet<br />
<br />
ComposerSheet {<br />
id: sheet;<br />
title: "Choose SubReddit"<br />
TextField<br />
{<br />
id: subRedditText<br />
}<br />
<br />
onCancelClicked: PopupUtils.close(sheet)<br />
onConfirmClicked:<br />
{<br />
changeSubReddit(subRedditText.text)<br />
PopupUtils.close(sheet)<br />
}<br />
}<br />
}<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2hn3_y1McPD6ux8o6qy6U9QIZuldq4LXKiP7OiFtfnqw_5uT57Pq_FJXS8OVdYDulPiLl7mqdveqmFcSG0iNGJnK2u5Zc2Dcg4HVfbuOPhElws8U9G-JWV86jIPYReXsHcoSxUZGLC_Al/s1600/screenshot2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2hn3_y1McPD6ux8o6qy6U9QIZuldq4LXKiP7OiFtfnqw_5uT57Pq_FJXS8OVdYDulPiLl7mqdveqmFcSG0iNGJnK2u5Zc2Dcg4HVfbuOPhElws8U9G-JWV86jIPYReXsHcoSxUZGLC_Al/s320/screenshot2.png" width="200" /></a></div>
<br />
<br />
As you can see, the ComposerSheet doesn't have size logic yet (or as likely I did something wrong), but none the less, it works!<br />
<br />
I got a surprising amount of free functionality from using Page, ToolbarActions, and ComposerSheet. On top of being easy and fun, it means that my app will inherit the look and feel, interaction patterns, translations and Ubuntu Touch style guidelines!<br />
<br />
<br />
<div>
<br /></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com2tag:blogger.com,1999:blog-7497847932106835950.post-63652235321571109452013-03-28T11:39:00.002-07:002013-03-28T11:41:14.300-07:00Time Waster Turbo Charge<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZqbExaT6G2IntSWPDATEOPQ97sjq3J76JA-60nr79a9APPs9u99jwy7KEiQu0YFRl9amTumIA7cacMT0SAsL6C75qjilL3Kcrac-PqolUQHP8fLtaxkqWdiyko9FAYMPELkBHFWGIgGDo/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZqbExaT6G2IntSWPDATEOPQ97sjq3J76JA-60nr79a9APPs9u99jwy7KEiQu0YFRl9amTumIA7cacMT0SAsL6C75qjilL3Kcrac-PqolUQHP8fLtaxkqWdiyko9FAYMPELkBHFWGIgGDo/s320/screenshot.png" width="200" /></a></div>
<br />
After my post yesterday about browsing 9gag.com, I decided I should make an even more efficient time waster. Way back in the day, I made an app called "<a href="https://launchpad.net/lolz">lolz</a>". But a lot has changed since then. Including the emergence of Imgur. Imgur is a service that hosts images for Reddit. And Reddit is the world's most efficient time waster.<br />
<br />
Also, <a href="http://api.imgur.com/">Imgur has a nice API</a>, so access to the data seemed pretty easy. Thus, I bring you, the greatest time wasting app of ever.<br />
<br />
Here's how I got started.<br />
<br />
QML often uses a Model-View-Controller architecture built in. I found that I can take advantage of this by for my app because. Specifically, the imgur app optionally serves up XML. If you have the option to get XML, use it! It makes things go much faster.<br />
<br />
So, the heart of the app as it exists today is my XmlListModel. An XmlListModel essentially turns XML into a list of objects or key/value pairs that other QML components can use. So, I made a model like this:<br />
<br />
XmlListModel<br />
{<br />
id: imagesXML;<br />
query: "/data/item";<br />
XmlRole<br />
{<br />
name: "imgURL";<br />
query: "link/string()";<br />
}<br />
}<br />
<br />
There are 2 parts, the first is the "query". This tells the model what types in the XML to look for. The picture from Imgur are "items" so I tell the model to look inside data tags for item tags.<br />
<br />
The second part is a set of XmlRoles. XmlRoles convert the info in the Xml tags into key value pairs for other components to consume. So, I tell it to make a key called "imgURL" that is paired with value of whatever string is stored in the "link" tag. In the imgur API, "link" is a url that goes directly to the image.<br />
<br />
But where does the XML come from? Typically, you would use the source property to point the XmlListModel to a url with xml. But this won't work with the imgur API because you need to set a header in the http request that includes your client idea for the API. Well, at least I couldn't figure out how to tell the XmlListModel to set a value in the header.<br />
<br />
However, I didn't fret. Instead I used good old javascript XMLHttpRequest to get the XML, and then to set the xml property for the list model. So I made an init() function that runs when the app is ready.<br />
<br />
function init()<br />
{<br />
var req = new XMLHttpRequest();<br />
var location = "https://api.imgur.com/3/gallery/r/funny/time/1.xml";<br />
req.open("GET", location, true);<br />
req.setRequestHeader('Authorization', 'Client-ID xxxxxxxx');<br />
req.send(null);<br />
req.onreadystatechange = function()<br />
{<br />
if (req.readyState == 4)<br />
{<br />
imagesXML.xml = req.responseText;<br />
activityIndicator.running = false;<br />
activityIndicator.visible = false;<br />
imagesView.visible = true;<br />
}<br />
};<br />
<br />
This function makes a request, and when it gets a response it sets the XmlListModel's xml property to the responseText. Again, this is very classic AJAXy programming. Then I do a few lines of setting the UI. You may notice that this includes making the imagesView visible. imagesView is the list view that I created to be the view for the model.<br />
<br />
ListView<br />
{<br />
visible: false;<br />
id: imagesView;<br />
model: imagesXML;<br />
<br />
orientation: Qt.Horizontal;<br />
anchors.fill: parent;<br />
delegate: MouseArea<br />
{<br />
height: parent.height;<br />
width: root.width;<br />
<br />
Image<br />
{<br />
width: root.width;<br />
height: parent.height;<br />
fillMode: Image.PreserveAspectFit;<br />
source: imgURL;<br />
}<br />
<br />
onClicked:<br />
{<br />
if(children[0].fillMode == Image.Pad)<br />
{<br />
children[0].fillMode = Image.PreserveAspectFit;<br />
}<br />
else<br />
{<br />
children[0].fillMode = Image.Pad;<br />
}<br />
}<br />
}<br />
}<br />
<br />
A ListView has 2 key parts. The first part specifies the model for the view using the model property. Easy enough.<br />
<br />
The second part is the "delegate". A delegate is the component that you create for each entry in the model. As you can see, I chose to make a MouseArea for each imgurURL. The MouseArea, in turn, contains an Image for displaying the image. The MouseArea is set up so I can do some interactions with the Image as desired. Currently, a tap toggles the Image between resizing to fit the size of the Image and displaying the Image at it's normal size.<br />
<br />
The great thing about the ListView is that it is a Flickable. So I get the nice flicking behavior of scrolling the list left and right for free! The ListView does other key things, especially, loading the images on demand. It only loads the images when they are scrolled into view. This saves a lot of network and memory resources.<br />
<br />
So, for the next features, I think I shall allow the user to choose a subreddit to browse.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com8tag:blogger.com,1999:blog-7497847932106835950.post-5167002633157034292013-03-27T07:42:00.000-07:002013-03-27T07:42:23.919-07:00Time Killer Extrordinaire<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjcy_h1w8oIadbP4_n4kox1_N7wb7t7iJLGBVRfsrQlblKcr790-j5MUhF9LWZVIZEKZPjhNSLUO_Ln8RO419cjBgiVqJfsS-9aPCt5fOdyTjBfCubi61YJG67maPSroOPkTjfBbHCMQ6Z/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjcy_h1w8oIadbP4_n4kox1_N7wb7t7iJLGBVRfsrQlblKcr790-j5MUhF9LWZVIZEKZPjhNSLUO_Ln8RO419cjBgiVqJfsS-9aPCt5fOdyTjBfCubi61YJG67maPSroOPkTjfBbHCMQ6Z/s320/screenshot.png" width="200" /></a></div>
Every morning I update to the new Ubuntu Touch Image [<a href="http://cdimage.ubuntu.com/ubuntu-touch-preview/daily-preinstalled/current/quantal-preinstalled.changelog">change log</a>] on my Nexus 7. Then at lunch, I "use" it to check Facebook and read funny posts. Lunch time time killing use case <b>nailed</b>.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com4tag:blogger.com,1999:blog-7497847932106835950.post-18170316929833274332013-03-19T17:51:00.001-07:002013-03-19T17:51:10.699-07:00Sweet Ubuntu Device QtCreator Integration<div class="separator" style="clear: both; text-align: left;">
I spent a bit of today using the Ubuntu Device integration features in Qt. It's fresh software, but it's really easy and fun. Here is the development version of the game I am running running on my desktop. Noticed that I set the size of the window and therefore the play area very intentionally. But, I had to think to myself "will the touch interactions work ok on my tablet?" "What about the sizes?". Fortunately, getting it onto my tablet is pretty easy.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnqMXK0XcSLDitXxXV-fPqewF0N9omQZ9-AktZyA_B-Zb28939T0W-_lQo2Mb4DObtus5P1FR94hObdzOuXtB3GBAIIG2QAF9bdD-wqVh8a4gqQji_ZCgM1VlgVEEg8TB3-O99pinV2_Bt/s1600/Screenshot+from+2013-03-19+17:09:11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnqMXK0XcSLDitXxXV-fPqewF0N9omQZ9-AktZyA_B-Zb28939T0W-_lQo2Mb4DObtus5P1FR94hObdzOuXtB3GBAIIG2QAF9bdD-wqVh8a4gqQji_ZCgM1VlgVEEg8TB3-O99pinV2_Bt/s320/Screenshot+from+2013-03-19+17:09:11.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
There is a device button in the left hand channel of QtCreator. I connected my Nexus 7 to my desktop via USB. Clicked Detect Devices, and there it is! Look at the many buttons that will make managing my device easier. For example, I am looking forward to trying the Upgrade to Daily Image button tomorrow. </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV9scX1OLORFkCkWKh6Czmpkzkj1oWCyCMwBLeEdQE-0LvKjTm69ZHQKL_IY9OAOmr1Wi5RXqmjjtmAdPnIv46ZfPRmAZdwrOOY4HpseAOSqhgfs9Qnz8vUDM4cG-TPcPrTT76KiXCMTck/s1600/Screenshot+from+2013-03-19+17:08:26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV9scX1OLORFkCkWKh6Czmpkzkj1oWCyCMwBLeEdQE-0LvKjTm69ZHQKL_IY9OAOmr1Wi5RXqmjjtmAdPnIv46ZfPRmAZdwrOOY4HpseAOSqhgfs9Qnz8vUDM4cG-TPcPrTT76KiXCMTck/s320/Screenshot+from+2013-03-19+17:08:26.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
So, how do I run it on my Nexus 7? I just use the command to do so! Notice there are other cool commands there too to try later. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWJ4yjnX9ZlzW8NvCilUoMMeLwiyFEE23y9eosBhHHsjZOrm_kMzHDJx0vUew00hfxXVli8NqWeeNP6MGPCbFCXBvgus7OxvHXxpSzeOR2By9GckbU9kAD9I4b3ci_dOv8zLFPVzEu1Bgs/s1600/Screenshot+from+2013-03-19+17:09:40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWJ4yjnX9ZlzW8NvCilUoMMeLwiyFEE23y9eosBhHHsjZOrm_kMzHDJx0vUew00hfxXVli8NqWeeNP6MGPCbFCXBvgus7OxvHXxpSzeOR2By9GckbU9kAD9I4b3ci_dOv8zLFPVzEu1Bgs/s320/Screenshot+from+2013-03-19+17:09:40.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
After picking "Run on Device" my app showed up on my tablet. As you can see from the screenshot, it had some issues! However, the touch screen worked the way I was hoping. Obviously, I need to think more about sizing and containment to make it all work correctly. Fortunately, it will be very easy to test it all.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMfMld7g_A0R8ijB1pAvZIRci8w-nmCVa-ttpVJDcQSXPhHS_V6sTCMceIb0WWHaO2R7N8xbURgqTcLelp5VbcX7HtY8hQTp0ERlIs4atyHJnfDUJ3AkdLc0t97JmmL-Dsc22ISJP6_J3F/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMfMld7g_A0R8ijB1pAvZIRci8w-nmCVa-ttpVJDcQSXPhHS_V6sTCMceIb0WWHaO2R7N8xbURgqTcLelp5VbcX7HtY8hQTp0ERlIs4atyHJnfDUJ3AkdLc0t97JmmL-Dsc22ISJP6_J3F/s320/screenshot.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Of course, I wanted a screenshot for this post. But how would I get that? With the Tools -> Ubuntu -> Device menu, of course! This menu has some other useful functions for managing the device. For example, the apt-get menu will allow me to install dependencies for my app.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF4zBRv_yOLHu3y5Rk2F2jBkI2r6a0YuzYm7cq52POsFvGe5548qCtgjDb9A0qDQhAxLk54HufoN4FMep0qDfPxkz0QDqpBKhCCmLLvI6_5MwKrGCsRPCoNdMW2Thv698POm62SwuIAcsr/s1600/Screenshot+from+2013-03-19+17:30:20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF4zBRv_yOLHu3y5Rk2F2jBkI2r6a0YuzYm7cq52POsFvGe5548qCtgjDb9A0qDQhAxLk54HufoN4FMep0qDfPxkz0QDqpBKhCCmLLvI6_5MwKrGCsRPCoNdMW2Thv698POm62SwuIAcsr/s320/Screenshot+from+2013-03-19+17:30:20.png" width="320" /></a></div>
All in all, I'm really pleased with the Ubuntu Device integration. It seems like will help make app development for my tablet and phone easy and fun.Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com6tag:blogger.com,1999:blog-7497847932106835950.post-27152157348659619362013-03-19T11:49:00.003-07:002013-03-19T11:49:53.230-07:00Extract Class Refactor Built in QtCreator<div class="separator" style="clear: both; text-align: left;">
Following up from my post about how I think about inheritance yesterday, I thought I'd do a quick post about a refactoring feature built into the QtCreator editor.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In this example, I decided I wanted to add a box that lets the user enter a name for a high score if they achieved it, and then to display all the high scores. I got started by creating an UbuntuShape with a column and sub components in main.qml, but quickly realized that I will have a lot of behavior and presentation to manage. This would be much easier to develop in it's own component (or "class" as I think of it).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So, I just right clicked in the editor and used the refactoring menu to "Move Component into Separate File." </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU5IR2rt5hwgW09PRQfSympvfJaMtyAudIk0Hb5_NUHX-S-ml0CeJPlFRq_8LxngACTT-xRDqDm2YtWNEhn5D-aAdB3-Do6CLg_auSqDTvajiFR_DO1mU5_sQ_RL1aX0L3tdMMg97Lm3cc/s1600/shot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU5IR2rt5hwgW09PRQfSympvfJaMtyAudIk0Hb5_NUHX-S-ml0CeJPlFRq_8LxngACTT-xRDqDm2YtWNEhn5D-aAdB3-Do6CLg_auSqDTvajiFR_DO1mU5_sQ_RL1aX0L3tdMMg97Lm3cc/s320/shot1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
I got a dialog that asked for a name, I chose "HighScoreBox" and it created a new file for me, and replaced all of my QML code in main.qml with just the little bit of code needed to declare the object.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTm6UM8kehZ9BVy84GdhXEh7pZpLvUxq9c7iW7cFbZBD5NP39pP6L1mg7OvNX8MyKVn85t_-VAXOL84umm3zWW5Okl4q3y6QQDYNODwzm_3BaKprAGfx4HBHMRIJWMBZWnp4fchHe1EU6M/s1600/shot2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="144" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTm6UM8kehZ9BVy84GdhXEh7pZpLvUxq9c7iW7cFbZBD5NP39pP6L1mg7OvNX8MyKVn85t_-VAXOL84umm3zWW5Okl4q3y6QQDYNODwzm_3BaKprAGfx4HBHMRIJWMBZWnp4fchHe1EU6M/s320/shot2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Now I am ready to properly develop the behavior for the component. Like any good refactoring tool, the code kept working. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH-mHI0IfSxXZvynGECufQZGVu4B50Rf3d2VKZD_9xBtBiDkOmWdy_z1bEN_o8x5zPEiBoOgxK9VvPSTnyRh_IJ7ODKAcMndhfqQUKRVxfZS7769j-4yQ72PXxU78zCNqwQT40bJFVEdHt/s1600/shot3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH-mHI0IfSxXZvynGECufQZGVu4B50Rf3d2VKZD_9xBtBiDkOmWdy_z1bEN_o8x5zPEiBoOgxK9VvPSTnyRh_IJ7ODKAcMndhfqQUKRVxfZS7769j-4yQ72PXxU78zCNqwQT40bJFVEdHt/s320/shot3.png" width="320" /></a></div>
<br />
<div>
<br /></div>
<div>
<br /></div>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com2tag:blogger.com,1999:blog-7497847932106835950.post-75955184833259208982013-03-18T09:14:00.000-07:002013-03-18T09:44:11.862-07:00How I Learned to Love QML and Inheritance Therein<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg13PkBXncPz3VLIkSdoiluJlpsed5acFWRFokU6q1EdRqfEQPCN3-kKUmQnKkwDtEScbMwMxzWy8XvwdGe1Af4OTUixELjbJ3PSQsAz4j9QWXtlK5uTuC3HCbcLj_0Vq_72D7JWXZ2Kiap/s1600/Screenshot+from+2013-03-18+09:09:26.png" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg13PkBXncPz3VLIkSdoiluJlpsed5acFWRFokU6q1EdRqfEQPCN3-kKUmQnKkwDtEScbMwMxzWy8XvwdGe1Af4OTUixELjbJ3PSQsAz4j9QWXtlK5uTuC3HCbcLj_0Vq_72D7JWXZ2Kiap/s320/Screenshot+from+2013-03-18+09:09:26.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Gotta love the "developer art" ... those placeholder images should be replaced by sweet Zombie artwork as the game nears completion.</td></tr>
</tbody></table>
For a long time I resisted the QML wave. I had good reasons for doing so at the time. Essentially, compared to Python, there was not much desktop functionality that you could access without writing C++ code to wrap existing libraries and expose them to QML. I liked the idea of writing apps in javascript, but I really did not relish going back to writing C++ code. It seemed like a significant regression. C++ brings a weird set of bugs around memory management and rogue pointers. While manageable this type of coding is just not fun and easy.</div>
<br />
However, things change, and so did QML. Now, I am convinced and am diving into QML.<br />
<ul>
<li>The base QML libraries have pretty much everything I need to write the kinds of apps that I want to write.</li>
<li>The QtCreator IDE is "just right". It has an editor with syntax highlighting and an integrated debugger (90% of what people are looking for when they ask for an IDE) and it has an integrated build/run system.</li>
<li>There are some nice re-factoring features thrown in, that make it easier to be pragmatic about good design as you are coding. I also like the automatic formatting features.</li>
<li><a href="http://qt-project.org/doc/qt-5.0/qtdoc/modules-qml.html">The QML Documentation</a> is not quite complete, but it is systematic. I am looking forward to more samples, though, that's for sure.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLiyE7wCXKyk5bIhBkxpTDKM5OQSjpn5GXl6BUkR10EI9YTI5_-G3UKhuXPv-ErcfFYDp4AuAVQX__h4nWXMnxvnN72VK4BvYUdBCbAwgFcA-buVEbRH6x4wanP_6n1qO7w1xUD_oGrXI9/s1600/Screenshot+from+2013-03-18+09:11:48.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLiyE7wCXKyk5bIhBkxpTDKM5OQSjpn5GXl6BUkR10EI9YTI5_-G3UKhuXPv-ErcfFYDp4AuAVQX__h4nWXMnxvnN72VK4BvYUdBCbAwgFcA-buVEbRH6x4wanP_6n1qO7w1xUD_oGrXI9/s320/Screenshot+from+2013-03-18+09:11:48.png" width="320" /></a></div>
<br />
In my first few experiences with QML, I was a tiny bit thrown by the "declarative" nature of QML. However, after a while, I found that my normal Object Oriented thought processes transferred quite well. The rest of this post is about how I think about coding up classes and objects in QML.<br />
<br />
In Python, C++, and most other languages that support OO, classes inherit from other classes. JavaScript is a bit different, objects inherit from objects. While QML is really more like javascript in this way, it's easy for me to think about creating classes instead.<br />
<br />
I will use some code from<a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/zombies/files/head:/qml/ZombieAttack/"> a game that I am writing</a> as an easy example. I have written games in Python using pygame, and it turned out that a lot of the structure of those programs worked well in QML. For example, having a base class to manage essential sprite behavior, then a sub class for the "guy" that the player controls, and various subclasses for enemies and powerups.<br />
<br />
For me, what I call a QML "baseclass" (which is just a component, like everything else in QML) has the following parts:<br />
<ol>
<li>A section of Imports - This is a typical list of libraries that you want to use in yor code. </li>
<li>A definition of it's "isa"/superclass/containing component - Every class is really a component, and a compnent is defined by declaring it, and nesting all of it's data and behaviors in curly brackets.</li>
<li>Paramaterizable properties - QML does not have contructors. If you want to paraterize an object (that is configure it at run time) you do this by setting properties.</li>
<li>Internal compotents - These are essentially private properties used within the component.</li>
<li>Methods - These are methods that are used within the component, but are also callable from outside the component. Javascript does, actually, have syntax for supporting private methods, but I'll gloss over that for now.</li>
</ol>
<div>
In my <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/zombies/view/head:/qml/ZombieAttack/CharacterSprite.qml">CharacterSprite</a> baseclass his looks like:</div>
<h3>
Imports</h3>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> import QtQuick 2.0
import QtQuick.Particles 2.0
import QtMultimedia 5.0
</code></pre>
<div>
<br /></div>
<div>
Rectangle is a primative type in QML. It manages presentation on the QML surface. All the code except the imports exists within the curly braces for Rectangle.</div>
<h3>
Paramaterizable Properties</h3>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> property int currentSprite: 0;
property int moveDistance: 10
property string spritePrefix: "";
property string dieSoundSource: "";
property string explodeParticleSource: "";
property bool dead: false;
property var killCallBack: null;
</code></pre>
<br />
<h3>
Internal Components</h3>
<div>
For readability, I removed the specifics.</div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Repeater
{
}
Audio
{
}
ParticleSystem
{
ImageParticle
{
}
Emitter
{
}
}
</code></pre>
<br />
<h3>
Methods</h3>
<div>
With implementation removed for readability.</div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function init()
{
//do some default behavior at start up
}
function takeTurn(target)
{
//move toward the target
}
function kill()
{
//hide self
//do explosion effect
//run a callback if it has been set
}
</code></pre>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Now I can make a zombie component by creating a new file called <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/zombies/view/head:/qml/ZombieAttack/ZombieSprite.qml">ZombeSprite.qml</a> and simply set some properties (and add some behavior as desired). Note that I declare this component to be a CharacterSprite instead of a Rectangle as in the CharacterSprite base class. For me, that is the essence of defining inheritance in QML.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> CharacterSprite
{
spritePrefix: "";
dieSoundSource: "zombiedie.wav"
explodeParticleSource: "droplet.png"
Behavior on x { SmoothedAnimation{ velocity:20}}
Behavior on y { SmoothedAnimation{ velocity:20}}
height: 20
width: 20
}
</code></pre>
<br />
I can similarly make a GuySprite for the sprite that the player controls. Note that<br />
I added a function to <a href="http://bazaar.launchpad.net/~rick-rickspencer3/+junk/zombies/view/head:/qml/ZombieAttack/Guy.qml">Guy.qml</a> becaues the guy can teleport, but other sprites can't.<br />
I can call the kill() function in the collideWithZombie() function because it was inherited from the CharacterSprite baseclass. I could choose to override kill() instead by simply redefining it here.<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> CharacterSprite
{
id: guy
Behavior on x { id: xbehavoir; SmoothedAnimation{ velocity:30}}
Behavior on y { id: ybehavoir; SmoothedAnimation{ velocity:30}}
spritePrefix: "guy";
dieSoundSource: "zombiedie.wav"
explodeParticleSource: "droplet.png"
moveDistance: 15
height: 20;
width: 20;
function teleportTo(x,y)
{
xbehavoir.enabled = false;
ybehavoir.enabled = false;
guy.visible = false;
guy.x = x;
guy.y = y;
xbehavoir.enabled = true;
ybehavoir.enabled = true;
guy.visible = true;
}
function collideWithZombie()
{
kill();
}
}
</code></pre>
<br />
So now I can set up the guy easily in the main qml scene just by setting connecting up some top level properties:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs-FcHYTspDizqcBDi85xaDMmaIiwOen0A-gcAMYTbaBYsqylXvgZgW-BqQUBfg__afl-YEFIvFyT6pHL8-NBDswGeCtpw9Y-Pd5vmKJSPgv9mfQ7ki3MOtt_n2HjCcJIT0l7C9NQNgP3G/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Guy {
id: guy;
killCallBack: gameOver;
x: root.width/2;
y: root.height/2;
}
</code></pre>
Rick Spencerhttp://www.blogger.com/profile/16312439500490748313noreply@blogger.com7