Friday, May 8, 2009

Multiple Image Scrolling

I thought through a couple different ways to allow users to see multiple images for a given node, and I decided that the simplest user interaction was just to have the image change to the next one when clicked on. It wasn't actually as simple to implement as it is to use. 

I created a Rectangle class extending the UIObject class, which the EventManager class sends events to. The rectangle also has a reference to the overall PApplet (Processing Applet), so as to control drawing this invisible rectangle on the screen. On a mouse click event, the EventManager sends the event to whatever UIObjects it knows of, and waits for one of them to handle it before resorting to other options. The Rectangle class handles MOUSE_RELEASED events that fall inside the area of the image. 

First roadblock - either the rectangles were responding to clicks indiscriminately, no matter where they were, or they weren't responding at all. Then when debugging through I realized the EventManager had references to a lot more UIObjects than seemed reasonable... until I realized that for every node on every new frame I was creating a new rectangle instead of updating that node's existing one. That lead to thousands of rectangles in a very short time and caused much of the strange click-response I'd been getting. 

Finding the click area itself was a bit of a task, because there aren't clear variables defining it. The function drawing the image is called using local coordinates, but my rectangle needed to be called using world coordinates. This is where my CIS 460 knowledge came in handy, because otherwise I wouldn't have even known the difference let alone how to handle it. I was able to find variables called realX and realY in world coordinates, which I thought would be the solution to my problem, except for some reason only the bottom left side of the image was responding to clicks. A lot of debugging and detective work lead me to find out that that the realX and realY coordinates are actually that location of the center of the node dot, not the top left corner of the image as I had previously thought. So even though my rectangle was drawn in the right place (tested in color, so I'd know where it was), the code deciding which clicks to recognize was handling the wrong area. 

Once I figured that out, the next step was to try and fix it. The image is drawn just to the right of that node dot, but how far? Some quick math got me a rough estimate, except that value changes depending on the zoom level. What solved it for me was the variable dotWidth, which changed along with the zoom. Turns out the image's top left side is approximately one "dot-width" away from the realX and realY coordinates. Since the dot hits at the center of the image, vertically, I subtracted half the height from the y coordinate and finally ended up with the correct "click area." 

The last step was to handle actually making a click do something other than print out "click!" which is what I'd been using to test it until then. After some quick searching around, I found that the ImageSearcher2 object has a next() function. So I called that. Nothing happened. Then I added a line for loadImageURL() and finally I had changing images on clicks! Except when it got to the end of the available images it stopped. So I added a check to restart from the first when it got to the end, and that is the long but exciting story about how I got my last feature working properly. 

I want to add some sort of way to check whether it's displaying the "Image not available" image, since that's annoying. But other than that, I do believe I'm done! 

Things I learned on this section: 
- PhyloWidget's handling of events and how to interact with it
- The image and node rendering processes, the many variables involved, and how much more hacked together it is than the rest of the code I'd been reading 'till now. 
- I'm a lot faster at debugging now, since a lot of this is trial and error, or rather "trial and figure out where the error is."
- Processing's shape-drawing language. I hadn't really gotten to interact much with it yet, and it was a nice introduction to how to draw shapes, specify coordinates and colors, etc. Of course you can't see my shapes, but they're there doing their job. 

With that, and since I just used all three forms of words sounding like "there" in one phrase, I consider this blog post done. 

Monday, May 4, 2009

UBIO Common Name Search...

...is complete! 

I've spent the past 2 days trying to work around strange bugs and get a working common name search, and I've got it. By yesterday I had the code parsing multiple pages in search of the right information and printing out the resulting common name in the console. Today I changed some of the set and get functions relating to labels so that a user could toggle whether the common or scientific name is displayed, and I now have the names actually displaying as labels on the rendered tree. I even figured out how to display a little message "Done searching for images!" just like there's a "Finished Loading Image!" message. 

Here's a sample image from after the name search/display has been done. It can't find every name, but it gets most of them.
I also spent some time reorganizing the toolbar menus so that they feel a little more intuitive and take fewer clicks to get to what you want. I felt the original structure of the toolbar lead to a lot of overlap and confusion about where a desired option was located. I organized my menus as follows: 

Tree
  • Layout (rectangular, circular, diagonal, unrooted)
  • Node (images and other annotations)
  • Label (unique, clade, show all, common name search)
  • Performance (anti-aliasing, animation)
  • Zoom
Format  
  • Font 
  • Style (size, scaling, angles)
  • Structure (sorting, flipping, branch lengths, etc.)
I think now the functionality of the program is actually arranged in a way that makes sense based on what the different options control and how they change the display of the tree. I also spaced them out a bit more, since I found that the original toolbar options were crowded into the left corner. Sample image: 

Sunday, May 3, 2009

UBIO Bugs

Current issue diagnosis: 

This form on the UBIO search page uses method="get" as opposed to "post", which the 2 image databases used. 

To connect and output data to the form, I create a URLConnection object, but its default method is post, not get (even though everything I've googled says that the default is get). Can't figure out how to change that setting to "get" because that's what I think is causing the output not to go through. 

Ideas, anyone?