Thursday, April 28, 2005

JukQuiz & Album covers

Created a fun little quiz game designed to test the knowledge of your music collection. JukQuiz will play a random song (that is in Juk's collection) and present you with a number of song title to guess from. It gives you ten seconds to try to guess the song, disabling incorrect options as the seconds go by. JukQuiz is a fun little addictive game that lets you see how well you know your music. JukQuiz uses DCop to communicate with Juk. For those Python or Ruby developers out there I challenge you to re-code this application your choice language.

The code is in kdeplayground-multimedia if you want to check it out.

Wednesday, April 27, 2005

Canon EOS 350D (Digital Rebel XT) digital camera

I have been planing on getting a new digital camera for about a year and had my eyes on getting a Canon 300D. Early last month I was finally going one and started looking around for deals. I went over to dpreview.com to read up on the 300D and noticed above it there was a link for a 350D (which had just been announced), but which was not yet released. So after months of waiting I decided it would be better to wait a few weeks for the 350D to be released. A bit of a downer after getting all excited about finally getting new camera. Most stores were not selling the 350D until the release date, but I found a teenager at my local best buy was happy to sell it. I have been using it for about a month and I have a few minor nitpicks, but otherwise am very happy with the camera.



dpreview.com's Canon EOS 350D review

Nitpicks
When looking into the center of the viewfinder you don't actually see all of the image that is captured. If you photographed something that was right up to what you see as the edge, the image will in fact capture a little extra all around. If you look from the top you can see the extra on the bottom and vice versa. When trying to fill the image with a subject this can be annoying.

Although it uses a CF slot and USB2 the USB connection is the usb-picture junk. I would have preferred it just show up as mass storage device. This was further confirmed as being an annoyance as I have been using gtkam to extract my images. This program ... well sucks. If you delete a file you have to restart the application. Turn the camera off/on, you have to restart. Don't refresh the view, restart the app. I don't have any faith that it can perform more then one action. Also double check that it actually saves your images to the hard drive because once it didn't and I deleted them of the camera before checking! I do *not* recommend using this program. It frequently segfaults and the fact that it made me loose my photos will most likely mean that I will never trust it again. Pick up a usb/cf adaptor.

The images are stored in numbered directories. The images themselves are just numbered sequentually. So you would have dcim/100/img_100.jpg Once you read 199 then it makes a new directory and put the images in there. A much better method was what my old Casio did (from three years ago) where the directories were the current date and the image's contained the date. For example you would have dcim/42705/42705_001.jpg If you took 999 photos in one day it would make a the directory 42705_2. It was very simple and best of all when I would finally get around to putting the images on my computer because typically I would only photograph one event a day all of my images were pre-sorted and named something nice. That is prefured to having all the photos from a week long trip in one directory named 1-79. You are forced to manually sort them. And a year down the line it is not handy seeing a random photo named IMG_22.jpg and wondering what year it was taken. There was really no configuration options for the file names so I created a quick script which will grab the date from the exif information and rename the files into the following format: "2005.04.27_001.jpg". Feel free to re-use it on your images that your digital camera produces.

#!/bin/bash
count=1;
for file in `ls -1 *.jpg *.JPG *.jpeg`; do
date=`exif.py $file 2> /dev/null | grep DateTime: | awk -F" " '{ print $3 }' | sed s/ASCII=//g | sed s/:/./g`
newfile=$date"_"`expr $count + 1000 | sed s/^1//g`;
mv -i $file ${newfile}.jpg;
let count=$count+1;
done

Monday, April 18, 2005

Grandmas don't use computers

You often are told that computers should be easy enough for grandma to use, so that if grandma wanted to make a rational database to manage her recipes, she could without reading a tutorial. The assumption that software should be made for grandma is fundamentally flawed. Why? Because every time someone talks about it, someone knows a friend who knows a friend, who's grandma writes her blog in vi. Because of these two extreme being pounded into my head when I think of grandmothers two images come to mind, the first is in a nursing home the second is some sort of super hacker. Which one of them do you think is true? Even if they were both true you don't want to target either one of them.

So who should software developers target for their easy of use testing? Who can't wont put up with software that is hard to use? Middle aged men that have kids or commonly referred to as "dads". They are young enough to know about the latest technology, old enough to have money to buy them, but don't have time for applications that don't just work.

Because there are kids in the house dads have very little time. They don't have time to try out every single option in a program or tweak their system like a twenty two year old collage student can. They just want things to work on the first try. Ok so maybe the output isn't optimal or the applications is a little slow, but the fact that it works on the first try and with very little learning curve will guarantee the dads allegiance to the software. Several of Apple's iLife applications have this down pat. The applications provide a limited functionality, but more then enough for someone who just wants to slap the data in and get something nice, quickly. One key thing which I will cover in a second is how many grandmas would use garage band v.s. how many middle age dads would die to be in a band and were drooling over garage band when it first came out? So maybe you can't choose the exact second the movie file is cut and you only have four ways it can be cut, but you don't have the time to anyway and that would just be anther confusing option. Software that is easy to use to get things done even if they don't have every feature will get the sales. Because of the kids dads will not put up with software that is hard to use just like grandmas, but dads have several other advantages over grandmas.

The important difference between grandmas and dads are that dads will purchase a whole lot more software then grandmas ever will. Dads typically are pretty versed in computers. They have probably owned a few themselves and work with them at their job. They enjoy using, tweaking, and like women, shopping for computers. Dads will frequently buy a game only to discover that they only ever played it twice. What do dads like more then games? Gadgets! And every gadget can connect to the computer these days, each one requiring some software to communicate and then plenty of software to manipulate the files, be it video, photo, or pinball machine roms.

The idea that all software should be targeted to grandma is deceiving. Grandmas do need things to be easy, but will probably only use their computer for e-mail, e-bay and perhaps some photo editing. But grandma wont buy your new wizbang application. Dads on the other hand also require that software be easy to use, but dads are much more likely to buy your software, the software sitting next to yours and oh and that scanner over that that is on sale too.

Monday, April 11, 2005

Why I hate the system tray

I think I figured out the key reason why I hate the system tray:
Applications that use the system tray make the user feel like they have less control.

Most application that use the system tray have some config option hidden somewhere to go either to the system tray or the taskbar so in theory users have complete control over where the application should go, but when you try to quit the application it laughs in your face telling you that it isn't going to quit, but go hide. As a user the reason I would put something in the system tray is because I want notification that its status has changed and/or I want to run it all the time. But as a developer I can't guaranty that either of these will be true for everyone that users my applications, so I am forced to screw some of them usability wise. What would be so much better would be if applications either started up in the system tray or not (whatever the developer though would be more likely) and then the *user* could drag the application from the system tray to the taskbar and vice versa and it would startup like that from then on. Those applications that didn't have systray support wouldn't have much use in being in the sys tray other then being a small image that runs all the time. Technically this would take a bit of thought on how to implement. But to a user closing application in the system tray would make it go back to the system tray (without the annoying slap in the face message box) while closing an application in the taskbar would make it quit.

I may want Juk in my system tray for a day or two while listening to a class seminar, but then when I don't use it as much I'll drag it out and it will go back to the task bar where it is just another application.

One definite area where KDE and windows both suffer is that the system tray and taskbar are so close together. In Gnome and OSX it is on the top of the screen. As a user I know what three or four (small icons) applications that I have running all the time and on the bottom of the screen much larger are my current running applications. Placing running applications right next to the system tray both of which are the same height doesn't distinguish them very much.

The current systray behavior is anti-intuitive and a bad user interface because it give the perception of letting the user be in control even if it isn't true.

Thursday, April 07, 2005

Qt programing in assembly

Spent lunch hacking up a Qt hello world application in assembly. Yes, I did do this because I found it (and things like this) fun. It isn't very portable and will probalby break if you try to link it to qt built by a gcc other then gcc3. Also I left the hard coded memory offsets in there. Feel free to "optimize" it. :) Of course this wouldn't be complete without a screenshot:



Copy the code into a file: "hello_world.s" and then run
gcc hello_world.s -lqt-mt
./a.out

File: hello_world.s
/**
* Qt Hello World in assembly
*/
.data
.HELLO_STRING:
.string "Hello World!"
.CONNECT1:
.string "1quit()"
.CONNECT2:
.string "2clicked()"

.text
.align 2

.globl main
main:
/* Store the stack */
pushl %ebp
movl %esp, %ebp

/* Create QApplication */
/* Arguments: argc, argv */
subl $260, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl 12(%ebp), %eax
movl %eax, 8(%esp)
leal 8(%ebp), %eax
movl %eax, 4(%esp)
/* Grab some memory */
leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplicationC1ERiPPc


/* Make a QPushButton */
/* Arguments: 0, 0 */
movl $0, 8(%esp)
movl $0, 4(%esp)
/* Grab some memory */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN11QPushButtonC1EP7QWidgetPKc

/* Make QString and set the button text to it*/
/* Argument: "Hellow World!" */
movl $.HELLO_STRING, 4(%esp)
/* Grab some memory */
leal -248(%ebp), %eax
movl %eax, (%esp)
/* Call the QString constructor */
call _ZN7QStringC1EPKc

/* Set the QString as the argument */
leal -248(%ebp), %eax
movl %eax, 4(%esp)

/* Grab some memeory */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QButton7setTextERK7QString

/* free QString memeory */
leal -248(%ebp), %eax
movl %eax, (%esp)
call _ZN7QStringD1Ev

/* Connect button press to quiting */
/* Arguments: QObject, button and clicked signal */
movl $.CONNECT1, 12(%esp)
leal -88(%ebp), %eax
movl %eax, 8(%esp)
/* arg 2 QObject, qapp and quit slot */
movl $.CONNECT2, 4(%esp)
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QObject7connectEPKS_PKcS1_S3_


/* set the main widget to be the button */
leal -232(%ebp), %eax
movl %eax, 4(%esp)
leal -88(%ebp), %eax
movl %eax, (%esp)
/* Set the button as the main window */
call _ZN12QApplication13setMainWidgetEP7QWidget


/* Show the button */
/* Call the show event on qapp */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QWidget4showEv


/* qapp exec */
/* Argument: the button */
leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplication4execEv


/* cleanup button and qapplication memeory */
movl %eax, -240(%ebp)

leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QButtonD1Ev

leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplicationD1Ev

movl -240(%ebp), %eax

/* exit the app */
leave
ret

Here it is in c++
#include "qapplication.h"
#include "qpushbutton.h"

int main( int argc, char **argv )
{
QApplication a(argc,argv);

QPushButton button(0);
button.setText( "Hello World!" );

QObject::connect( &button, SIGNAL(clicked()), &a, SLOT(quit()) );
a.setMainWidget( &button );
button.show();

return a.exec();
}

Popular Posts