Archive

Posts Tagged ‘XUL’

Understanding nsITreeView getCellProperties and getRowProperties

June 18th, 2006

You may have read the following text from xulplanet

An atomized list of properties for a given cell. Each property, x, that the view gives back will cause the pseudoclass :moz-tree-cell-x to be matched on the ::moz-tree-cell pseudoelement.



and start scratching your head wondering what it means. After searching through mozilla source for some examples of how getCellProperties or getRowProperties work, I finally figured it out and have a much greater respect for how the nsITreeView can really be customized. First an example of styling a specific cell and a complete row, assuming you already know how to setup your own nsITreeView:



The getCellProperties in our nsITreeView, checks the status column on a row and sets a property record_closed if the records status is closed:

 getCellProperties: function(row,col,props){
  this._fetchToRow(row);
  var record = this.records[row];
  if( record.status == "Closed" ){
    var aserv=CC["@mozilla.org/atom-service;1"].getService(CI.nsIAtomService);
    props.AppendElement(aserv.getAtom("record_closed"));
    if( col.id == "status_id" ){
      props.AppendElement(aserv.getAtom("record_status_closed"));
    }
  }
}

So, what is this property on the cell ‘record_closed’ and ‘record_status_closed’? It made sense to me once I found this using lxr, and realized I could control the style on the cell using it like this:

treechildren::-moz-tree-cell-text(record_closed,record_status_closed) {
text-decoration:line-through;
font-weight:bold;
}
treechildren::-moz-tree-cell-text(record_closed) {
color:gray;
}

Basically, it works like a CSS attribute selector.

So, now I can style the column that indicates the status as closed with a line through and color each of the cells with a gray font. getRowProperties works the same you just can’t effect the cell fonts, but you can effect the whole row background.

Software , , ,

Using nsISAXXMLReader and my nsIChannel Woes

May 29th, 2006

My first pass was to use nsIIOService to create an nsIChannel. This worked and gave me time to focus on getting my parser methods correct.

function runRestoreFromChannel( urlSpec, progress )
{
 var ioService = CC["@mozilla.org/network/io-service;1"].getService(CI.nsIIOService);
 var reader = CC["@mozilla.org/saxparser/xmlreader;1"].createInstance(CI.nsISAXXMLReader);
 var channel = ioService.newChannel( urlSpec,null,null );

 channel.notificationCallbacks = progress;
 reader.contentHandler = new RestoreParser( broker, progress );

 reader.parseAsync( null );
 channel.contentType = "text/xml";
 //channel.loadFlags = CI.nsIRequest.LOAD_BACKGROUND;
 channel.asyncOpen( reader, null );
}

This solution has one major flaw. The nsIFileInputStream that’s created reads in very large chunks from the filesystem for performance. The problem is during my parse I do some fairly intensive I/O operations as I read my data in. But since, almost all the data is read in by the nsIInputStream, it means my GUI is locked up while I’m processing the data. To get around this I thought about writing my own nsIStreamListener and controlling how the data is passed to my nsISAXXMLReader. The problem there is I’d either have to buffer all the data or still be stuck in a loop on the main thread blocking the UI. Ideally, I’d be able to run the parser in a background thread at full speed. As a simple workaround I can use nsIInputStreamPump. It works almost identically to using the nsIChannel, except I can specify how much data to read at a time (i.e. the chunk size). There was one minor little problem that can be worked around using a custom nsIStreamListener around the nsISAXXMLReader.

Here’s the code for setting up the parser:

var reader = CC["@mozilla.org/saxparser/xmlreader;1"].createInstance(CI.nsISAXXMLReader);
var filestream = CC["@mozilla.org/network/file-input-stream;1"].createInstance(CI.nsIFileInputStream);
var pump = CC["@mozilla.org/network/input-stream-pump;1"].createInstance(CI.nsIInputStreamPump);
var ioService = CC["@mozilla.org/network/io-service;1"].getService(CI.nsIIOService);
var channel = ioService.newChannel( urlSpec,null,null );
var uri = ioService.newURI( urlSpec, null, null );

filestream.init(file, 0x01, 0444, 0);

reader.contentHandler = new RestoreParser( broker, progress );

reader.parseAsync( null );

pump.init( filestream, -1, -1, StreamChunkSize, 1, false );
reader.baseURI = uri;
pump.asyncRead( new StreamListener( reader, progress, channel ), null );

Here’s the code for wrapping the nsIStreamListener:

function StreamListener( reader, progress, channel )
{
 this.reader = reader;
 this.progress = progress;
 this.channel = channel;
}
StreamListener.prototype = {
 reader:null,
 onStartRequest: function( request,context ){
   dump( "starting\n" );
   // XXX: passing channel here to work around bug in nsParser.cpp
   this.reader.onStartRequest( this.channel, context );
 },
 onDataAvailable: function( request, context, input, offset, count ){
   dump( "offset: " + offset + ", count: " + count + "\n" );
   // XXX: passing channel here to work around bug in nsParser.cpp
   this.reader.onDataAvailable( this.channel, context, input, offset, count );
   this.progress.onProgress( request, context, offset, offset + count );
 },
 onStopRequest: function( request, context, status ){
   // XXX: passing channel here to work around bug in nsParser.cpp
   this.reader.onStopRequest( this.channel, context, status );
 }
};

Software , , ,

Accessible XUL Window Sizing

September 21st, 2005

Today, I ran into a problem with a window sizes, when I started trying to run SimoHealth using High Contrast Mode. Basically, what I wanted to figure out is can I initialize the window size so that it is both optimal for the normal case as well as the accessible case. My first solution was to just call window.sizeToContent on load. The problem with this is when you have a wizard with multiple pages and the first page is not the largest page then you end up with a wizard that is too small.

The solution I came up with is pretty simple, pick a default size that works for the normal case and then for other cases that the content of the page exceeds the default let the window grow. Basically, this is like setting a min size or preferred size.

// width, the preferred width,
// height, the preferred height
function setInitialDialogSize( width, height )
{
window.sizeToContent();

var nwidth = window.outerWidth;
var nheight = window.outerHeight;

dump( "nwidth: " + nwidth + ", nheight: " + nheight + "\n" );

if( nwidth < width ){
nwidth = width;
}

if( nheight < height ){
nheight = height;
}
window.resizeTo( nwidth, nheight );
}

Software ,

XUL Datepicker XBL Binding

September 14th, 2005

I’ve been using this great datepicker for some projects. The only thing about it that hasn’t been very nice is that its an overlay so when used you have to be careful about mixing up ids. I typically use it with an input box and a nice calendar button. So, building on the work of the datepicker I bundled it into an easy to use XBL widget.

datepicker XBL binding
Updated Link:datepicker XBL binding

to use it unpack the tar ball, and add some css like:


datepicker{
-moz-binding: url("chrome://package/content/datepicker.xml#datepicker");
}

Also, note that you’ll have to go through the files and fix the chrome paths to match the package your using the datepicker from.

Software , , ,

ProjectRidley and XUL on the Desktop

August 21st, 2005

It looks like the future is very bright for gtk+ and the gnome world. Not only is the focus now on the consolidation of the many gnome libraries into the gtk+ toolkit , but there is also discussion now about using XUL for the desktop.

Software ,

XUL Dev Setup

July 18th, 2005

I started the night thinking about a XUL data modeler program to make it easier to visualize SQL data tables or maybe RDF. Having run into some stumbling blocks and really having a hard time focusing in general – I decided to devote my energies to making it easier to start new projects… Although, it should have been a perl script, I think it’s more interesting as a XUL Wizard.

screenshot:

source

Software , ,

XUL Music Gets PodCasting!

June 29th, 2005

I just spent the last 12 hours, really giving xulmusic some love.

Lots of corners rounded and many more roughened up with new features.

I added a first pass options dialog and a simple about dialog box.

By far the coolest feature is support for podcasting. I still have some more work to do with this, like:

1. download progress meter, per stream.
2. updating content timers (configuration option required).
3. fix next and previous to ignore podcast headers.

It doesn’t look like I’ll have a mac version for 0.3, but I will definately have it built for a 0.4 release.

My goals for version 0.3 are:

  • podcast rss feed support
  • streaming music (shoutcast)
  • installer (stand-alone)

I’ve recieved a lot of really great feedback on the 0.2 release. Here’s some of the names suggested by Mike:

  • fireplayer
  • crossplayer
  • icebird
  • talon
  • shadowfire
  • audifox/audibird
  • melody

The feature list suggested by Mike:

  • support extensions like firefox
  • randomize playlists
  • include a system tray icon (win32/gnome/kde)
  • support for flac/shn/etc.. (maybe format support can be added in extensions)
  • make the program stand-alone with an installer
  • themes/skins (like xmms/winamp)
  • support for streaming music (shoutcast)
  • get a cool logo (related to name?)
  • podcast rss feed support

Software , , ,