Archive for September, 2010

SlashXML

I recently put up the SlashXML library on bitbucket. SlashXML provides a way to retrieve data from an XML document via path names to elements. It’s somewhat in the same vein as XPath, but much simpler. I wrote this way back when because I was annoyed at the more conventional method of having to extract data during the depth-first traversal of the document tree – this is a fine way to parse the document and pull in the data but not necessarily the most elegant way to query it. I haven’t written any documentation so, as I did with the bluetooth stuff, I’ll post a quick-and-dirty tutorial here.

The C# code files and .NET DLL are up now (/cs folder). I do have a version of this in C++ which uses TinyXML, but there’s a major bug that needs to be resolved before I upload it.


Load an XML document from a file

SlashXML.SlashXMLReader xmlReader = new SlashXML.SlashXMLReader();
xmlReader.LoadXMLFile(filepath);


Load an XML document from a string

SlashXML.SlashXMLReader xmlReader = new SlashXML.SlashXMLReader();
xmlReader.LoadXMLString(xmlString);


Retrieve data from an element

string data = xmlReader.GetDataAt("root/child");

If the element doesn’t exist, has no data, or contains other elements instead of data, the return value will be null.


Retrieve data from an indexed element

string data = xmlReader.GetDataAt("root/child[2]");

Indexing on data read in occurs when there are multiple elements with the same name.


Get the number of child nodes under an element

int numChildren = xmlReader.GetNumChildren("root", "child");


Note that underlying SlashXML.SlashXMLReader is SlashXML.StringTreeUtility.StringTree which actually holds the data read in and which can be queried directly for the data. Also, SlashXML reads everything into memory – do not use this for massive files (e.g. 1GB+ documents)! In fact, you should probably reconsider your use of XML if your files are that massive.

You’ll notice a major missing feature here – retrieving data in attributes! It’s not too difficult to do, but I haven’t had time to do it. It’ll be in a future version.

hotspotdot for webOS v1.1.0

The 1.1.0 update for the hotspotdot webOS app is up. You can now create a new account from within the app, share hotspots via. email, update the locations of your existing hotspots, and refresh the current list of hotspots.

hotspotdot webOS screenshot 1 hotspotdot webOS screenshot 2 hotspotdot webOS screenshot 3

I can’t respond to reviews in the app catalog, so I’ll do it here.

Potential = 5 stars. Currently, still a work in progress – but fills a much needed void on webOS = being able to save fav places in google maps.

2 features missing:

1. Search via keyword/category. You can enter keywords for your places, but then it just shows everything in a list anyways. Maybe make it autosearch – when the program is open you can just starts typing and the matching entries will pop up.

2. Ability to enter places you aren’t current at. Right now to add any place you have to physically be there. This prevents the most common use of fav places = hear about a good restaurant from a friend and save its location so you can go there later.

Hope to see this developed more…and i’d pay for it!

I’ll definitely work on autosearch. Adding locations that your not currently at is problematic because there doesn’t seem to be a mechanism on webOS by which you can poll the locations of a selected marker from the Maps app. You can, of course, do this from the web app.

2 stars because it functions & is a cool idea….BUT…this is clearly not formatted for WebOS (Or maybe mobile?). I say that because you have to sign up 1st & when the sign in screen loads it is so small as to be unreadable. Once you expand the screen to enter you info, you have to slide aound to get it all in and “submit”.

That might sound harsh/anal but it is the simple things – like useability – that frustrate users and make them look elsewhere.

From Chris T

Very true, the sign-up process was not part of the app prior to this version and the process via. the website really was not designed for a mobile device – though everything should work. This version should make the process more mobile-friendly.

Ok.. Not really what I expected.. I was reading into this as WiFi hotspot designator.. Just a basic location designator?? Uh..ok…

From Anonymous

I was hoping it would perhaps look for “HotSpots”, posibly reporting strength, then recording GPS location, like a sniffer.

From Mark R

There seems to be some confusion that the app deals with wifi hotspots. To (hopefully) avoid this, I’ve altered the app description to the following:

hotspotdot allows you to easily record and tag locations (“hotspots”) that are important to you. Your personal database of locations (and related metadata) can then be accessed to show you exactly where your hotspots are and how to get to them.

Finally, for bug reports, feature requests, etc. you can now email me at aautar@hotspotdot.net.

Share hotspots via email

A small, but useful addition to hotspotdot: you can now share hotspots via. email.

hotspot shared via. email, shown in gmail client

Currently only available on the web client, but this and a few other features will soon make their way into the webOS mobile app.

At one point I did consider making a larger social networking component integrated into the site – sharing hotspots with other hotspotdot users – however, I don’t think this would have been very useful, certainly not to me. In many ways hotspotdot is fairly anti-social, focused much more on functionality revolving around maintaining your personal repository of locations rather than the current location of your friends and whether or not they’ve checked-in at some commercial venue; the concept underlying other location services such as Google Latitude, foursquare, and Facebook Places.

Attaching a title to a position on Google Maps

One of the neat little things I discovered when doing the hotspotdot webOS app is how to show the custom, user-entered title of the location, as shown below.

Google map location on webOS

This is done by specifying the title in the query, in parentheses, after the coordinates. The full, escaped query URL for the location above is as follows:

http://maps.google.com/maps?q=40.7044120969184,-73.99009709643556%28Empire%20Fulton%20Ferry%20State%20Park%29

The Javascript code for the webOS app would look something like this (latlong and title are variables that hold the latitude, longitude coordinate pair and title, respectively):

this.controller.serviceRequest("palm://com.palm.applicationManager", { method: "open", parameters: { id: "com.palm.app.maps", params: { query: escape(latlong) + "%28" + escape(title) + "%29" } } });

This works in the browser as well, so the URL shown above would display the following,

custom title on Google maps position

hotspotdot for webOS

I originally conceived hotspotdot as a smartphone app, as its utility meshes perfectly with a smartphone’s GPS receiver, but the contest I was entering (Microsoft’s My App is Better Challenge) required a web app. The web app is useful but when it comes to adding a hot spot it’s hard to beat hitting a button and pulling in your global position instantly.

Anyways, the bottom line is I went ahead and built the mobile app anyway. I have a Palm Pixi, so I built it for webOS.

The app was approved and published in the app catalog a few hours ago, so anyone with a Palm Pre or a Palm Pixi should be able to get it soon. It’s free. Also, you’ll need an account at my.hotspotdot.net to use it (sorry, I didn’t add support for account creation within the app).

hotspotdot webOS screenshot 1 hotspotdot webOS screenshot 2 hotspotdot webOS screenshot 3

This if my first webOS app and my first mobile app!

The Mojo framework proved to be fairly approachable. Making everything Javascript + HTML-ish markup was a very good call. However, a few bits of criticism:

  • I ran into some annoyances due to nothing more than flaky documentation. I should say 99% of the documentation is very good and thorough, but small bits of missing info, like needing the .mojo prefix for method calls, can drive you up the wall.
  • A intermediate-level tutorial would have been very much appreciated. Palm has the Getting Started tutorial followed by the fairly advanced Client-Server tutorial.
  • At various point in the documentation (e.g. here) there are examples of declaring buttons in a simpler way, entirely within the DOM (no setupWidget call necessary) and no x-mojo-element attribute on the div. This shortcut should probably be avoided; you have to understand that all you can do with these elements is respond to the Mojo.Event.tap event – you can’t change the underlying model, label, etc.
  • To manipulate/update widgets, you need to modify the widget’s underlying model (an array of properties). This was somewhat surprising to me. I would have figured, in keeping with the JS + HTML scheme and how things are done in an AJAX web app, you would modify the DOM of the view to change things.
  • Mojo uses the Prototype framework. Prototype is okay… AJAX calls are simple enough, but XML parsing was a bit more difficult compared to jQuery, which is more powerful for traversing and pulling elements out of an XMLDocument.
  • You have to work in Eclipse for an integrated IDE experience. I would have much preferred a Netbeans plug-in.

Overall, I’m still pretty happy with the Mojo framework and I was able to code, test, and deploy an app fairly quickly (~2 weeks, working on this on and off; probably less than 72 hours total).

Beginning of the end for the laptop

Something I said a few months ago in a previous post,

…tablets are a new form of computing devices, one poised to become more powerful and user-friendly than the netbook/laptop form…

I mentioned the JooJoo in that post, but the iPad pretty much demolished any chance the JooJoo had at success.

The iPad itself has done phenomenally well and my optimism for tablets seems to be shared by the general public. Despite lackluster first impressions of the iPad on tech sites when it was announced, the iPad has managed to sell at a staggering rate (2 million sold, 2 months after going on sale).

My prediction of the tablet overtaking the netbook and laptop form-factors seems to be coming true as well; from the Wall Street Journal,

…internal estimates [at Best Buy] showed that the iPad had cannibalized sales from laptop PCs by as much as 50%.

Nice summary at SAI.

Changing the model of activity buttons on webOS

This little issue drove me insane: you can’t change the model on an activity button after it’s been activated.

So, first, a little background. webOS/Mojo has widgets and one type of widget is a button. Setting up a button requires attributes (to set type – default or activity button) and a model (to set the label, disable/enable, and associated CSS class). A type of Mojo.Widget.activityButton turns the button into an activity button, which adds a spinner (preloader) to the button when the Mojo.Widget.Button.activate() method is called. The Mojo framework also allows altering the model of any widget and calling the Mojo.Controller.SceneController.modelChanged() method to commit the updates.

Here’s some code to show how all of this pieces together. This code is correct and functions as expected.

function setupSignInButton() { var btnModel = { buttonClass: "affirmative", label : "Sign in", disabled: false } var btnAttributes = { type: Mojo.Widget.activityButton } ctrlr.setupWidget("signin-button", btnAttributes, btnModel); Mojo.Event.listen(ctrlr.get('signin-button'), Mojo.Event.tap, function() { btnModel.disabled = true; btnModel.label = "Signing in..."; ctrlr.modelChanged(btnModel); ctrlr.get('signin-button').activate(); }); }

Note, ctrlr is a reference to the scene controller (Mojo.Controller.SceneController).

When the button is tapped, the spinner is activated, the button is disabled, and the label for the button is changed to “Signing in…”, as shown below.

webOS activity button, signing in

The problem is, if you move the call to activate { ctrlr.get(‘signin-button’).activate(); } above the call to change the model { ctrlr.modelChanged(btnModel); }, the model change does not occur. So you have an activated button without the model change, as shown below.

webOS activity button

Note, deactivating the button and attempting the model change does not work.

Edit: After playing with the code a bit more, turns out there’s no need to call activate(), the activity button is activated automatically when the button is tapped. Also, the issue I mentioned above seems to all stem from the call to activate(). It seems no code after the activate() call is executed (I attempted to show an alert dialog) and very much looks like an issue where the activate() call is blocking.

Edit 2: Hmmm, turns out nothing was being blocked, but an uncaught exception was being thrown. If you call a method for a widget as I was doing above, something like the following is thrown:

TypeError: Object# has no method 'activate'

To call a method, you need to put ‘.mojo’ before the method name, so:

ctrlr.get('signin-button').mojo.activate();

Not quite fulfilling…

Apparently I’m not good at reading nor following rules.

my app is better contest, rejection email

I’m guessing this has to do with the fact that I used Google Maps for hotspotdot instead of Microsoft’s Bing Maps, with the Google logo plainly visible on the map.

It never crossed my mind that this might be an issue. Trademark or not, using components from a variety of vendors is pretty much the norm for any sort of web development or web design.

Repressed memories don’t exist

Fascinating, enlightening article,

… memory usually works in the opposite way, with traumatised people reliving experiences they would rather forget.

In a briefing to the US Supreme Court, Professor Richard McNally from Harvard University described the theory of repressed memory as “the most pernicious bit of folklore ever to infect psychology and psychiatry”.

He maintains false memories can easily be created by inept therapists.

“The stress hormones that are released during a trauma tend to consolidate the memory, make it rather strong and sometimes even intrusive, as you see in post-traumatic stress disorder,” he said.

Consumed by the desert

I came across this a while back on Fast Company’s Co.Design, showing the abandoned town of Kolmanskop, Namibia, once home to German diamond miners. After the diamond fields dried up, residents gradually moved away, turning Kolmanskop into a ghost town by the 1950s and leaving it prey to the sands from the desert.

house in Kolmanskop, Namibia

Follow the link to see the rest of the pictorial.

The photos are by Alvaro Sanchez-Montañes. His portfolio is increadibly impressive and definitely worth a look.