A new year, a new example, and various other bits of progress

News and Announcements

Well it's been a while, but have no fears, progress on the upcoming Fish Taco release is moving forward, albeit slower than I would like.

The latest example was kind of cool, and I wanted to post about it. It is based on a little article by Ryan Paul at Ars Technica: U CAN HAS LOLcats on Linux with Ruby and GTK. This inspired me to write the equivalent using the VCF:

This demonstrates a number of new features, namely the UI is completely defined in the VCF's VFF format, the xml retrieval code is done using the AsyncURL class, the XML parsing and XPATH search is done using the new XMLKit (based on the libxml library from xmlsoft.org), and the display is managed with the HTMLKit's HTMLBrowserControl.

The example also exercises the use of VFF by defining the UI with a toolbar, loading up images into an ImageList, showing how to refer to images/files within the Resources directory of the application,embedding child control's in a toolbar, and so forth. Loading up the feed from "http://feeds.feedburner.com/ICanHasCheezburger/" was easy, for example:

CallBack* cb = getCallback( "LOLCatsApp::urlComplete" );
AsyncURL* url = new AsyncURL(feedURL);
url->DataComplete += cb;
url->get();
Then we just parse it in our callback:
AsyncURL* url = (AsyncURL*)e->getSource();

String xml = url->getDataAsString();

String html;
html += "<html><body style=\"background-color: #F7F7F7\">\n";

XmlDocument doc;
doc.setXML(xml);
XPathIterator xp(doc);
Dictionary nsDict;

nsDict["media"] = "http://search.yahoo.com/mrss";
xp.registerNamespaces(nsDict);	

XPathNodeIterator it = xp.selectNodes("//media:content");

while ( it != xp.end() && !it.isNull() ) {

	const XmlNode& n = *it;		
	
	String imageURL = n.getAttribute("url");

	html += "<div style=\"border: 3px outset grey\"><img width=\"100%\" src=\"";
	html += imageURL;

	html += "\"></div><br>\n";

	it ++;
}

html += "</body></html>";		

FileOutputStream fos(lolcatsFile);
fos << html;
There may be a namespace issue in the XMLKit code, which is why I had to manually add it to the dictionary. I'll be looking into that.

Any how, I thought this was kind of neat and wanted to share. The VFF file, should anyone care, looks like this:

object LOLCats  : VCF::Window
	top = 200
	left = 200
	height = 500
	width = 500
	caption = 'You Can Has LOLCAT'

	object images : VCF::ImageList
		transparentColor.red = 0
		transparentColor.green = 0
		transparentColor.blue = 0
		
		imageWidth = 24
		imageHeight = 24

		object img1 : VCF::ImageComponent 
			filename = 'res:refresh.png'
		end

		object img2 : VCF::ImageComponent 
			filename = 'res:quit.png'
		end

		object img3 : VCF::ImageComponent 
			filename = 'res:home.png'
		end
	end

	object toolbar : VCF::Toolbar 
		alignment = AlignTop
		height = 25
		showButtonCaptions = true
		imageList = @images;


		object refreshBtn : VCF::ToolbarItem
			imageIndex = 0
			caption = 'Refresh'
		end

		object quitBtn : VCF::ToolbarItem
			imageIndex = 1
			caption = 'Quit'
		end

		object homeBtn : VCF::ToolbarItem
			imageIndex = 2
			caption = 'Home'
		end

		object sep : VCF::ToolbarItem
			separator = true
		end

		object updatePanel : VCF::Panel 
			border = null
			width = 120

			object updateLabel : VCF::Label 
				alignment = AlignLeft
				caption = 'Update interval:'
				width = 80
			end

			object updateFreqEdit : VCF::TextControl 
				alignment = AlignClient
				text = '10'
			end
		end
		

		object btn4 : VCF::ToolbarItem	
			caption = 'Update interval'
			itemControl = @updatePanel
		end
	end

	object browser : VCF::HTMLBrowserControl 
		alignment = AlignClient
		allowPopups = false
		allowTextSelection = false
		allowContextMenu = false
	end

	object statusBar : VCF::StatusBar
		status[0] = 'Last update: '
	end	

	object timer : VCF::TimerComponent
		timeoutInterval = 600000 //10 minutes
		active = true
	end
end