Home | Shorter Path | About Me
Home
About Me
RSS Feed

Planners (you know you want it)

Archive

2004

01

02

03

04

05

06

07

08

09

10

11

12

 

2005

01

02

03

04

05

06

07

08

09

10

11

12

 

2006

01

02

03

04

05

06

07

08

09

10

11

12


Blogroll
 
Borland
Allen Bauer
Anders Ohlsson
Chris Bensen
Malcolm Groves
Michael Swindell
Steve Trefethen
Borland Blogs
TeamB
TeamB Blog Server
Nick Hodges
Other
Algorithms for the Masses
Brad Abrams
Chris Brumme
Chris Pratley
Dan Miser
Don Box
Falafel Flogs
iunknown.com
Joel on Software
Matt Pietrek
Suzanne Cook
The Daily WTF
The New Old Thing
Wintellog

Archive for 10/2004

Clicking and the art of user interface design
Wednesday, October 20, 2004 04:17 PM

Raymond Chen discusses double-clicks (and higher-order clicks). For years, mouse clicks were interpreted in a fairly standard manner: clicking an item selects it, and double-clicking it activates some default action, like displaying a window and editing the selected item. The mouse messages logic in Windows is tuned to support this model. Other models, as demonstrated in Raymond's posts, require some trickery.

One model in particular caught my eye. In this model, both a single-click and a double-click invoke an action, but the single-click action is only invoked if the user will not double-click. Since there's no way of knowing whether the user will click the mouse again, the trick here is to delay the single-click action for the amount of time specified for double-clicks (in the Control Panel's Mouse applet). If the user doesn't click the mouse within that period, the application can run the single-click action.

The "clairvoyant" mouse input model is getting pretty common these days. I've implemented this model for the in-place editors in Planners, and even though Windows has no internal support for it, it is implemented by parts of the Windows user interface, such as Explorer. The model belongs to a family of user interaction techniques that go beyond the simple, deterministic rules of the past, and try to interpret the user's intention. In other words, "Do What I Mean".

We see more and more DWIM algorithms in modern software, and have come to expect them. For example, many program support text selection using several mouse operations. You can push the mouse button and select an arbitrary portion of the text, but if you move past a word boundary the selection model changes and selects complete words. A single click positions the caret, a double-click selects a word, and a triple-click selects an entire paragraph. This model is even supported internally by the Rich Edit control in Windows.

A lot of the time, these models are the result of usability testing. Watching how users interact with software, figuring out what their intentions were, then teaching the software how to interpret the user's actions. Other times, we just copy such behaviors from programs we find easy to use. In fact, it's important that we, as developers, do that. It let's us provide a consistent interface to our end-users, making our programs easier to use and - hopefully - more attractive.

Implementing such behaviors isn't easy, but these days it's absolutely crucial. The main problem isn't the actual implementation - if you take a look at Raymond's posts you'll see the code is fairly trivial - it's correctly analyzing the correct process to implement. One of my favorite examples is the way programs handle multiple selection and drag-and-drop. This process is so complicated that it's difficult to find two programs that handle it exactly the same. Here's how Windows Explorer handles it, roughly:

User Action Behavior
Mouse down Set focus to the item pointed to by the mouse. If the item was not already selected, select it and unselect any previously selected item.
Ctrl + Mouse down Set focus to the item pointed to by the mouse. If the item was not already selected, select it. Otherwise, unselect it. In any case, do not change the selection status of any other item.
Shift + Mouse down Set focus to the item pointed to by the mouse. Select all items between the previously focused item and the newly focused item, inclusive, unless the new item is already a part of a range selection, in which case select all items between the first item selected in the previous range selection and the new item, inclusive.
Mouse up If after a mouse down operation causing the selection of a single item that was already selected, unselect any previously selected item, and set the timer.
Double click Open all selected items and clear the timer. Do not change the selection status of any item.
Mouse move Start dragging.
Timer If a single item was selected, and no other mouse action occurred since the mouse up action that set the timer, activate the in-place editor to rename the file.

The table above is incomplete: it only includes left-button handling on file names. Other things, like the right mouse button or focus changes, can affect this behavior. Also, when clicking on file icons rather than on file names, the rules change a little. You can even select ranges using the mouse (without using the Shift key).

Notice the different selection behavior for single items: if an item isn't selected, pushing down the left mouse button is enough to select it and unselect any other item. If an item is already selected, other items will only be unselected when you release the button. This is implemented to allow the user to drag multiple items while still responding to user requests as soon as possible. Ideally, a single click selects an item as soon as you push the button. If Explorer did that, however, you would never be able to drag multiple items without using the Ctrl or Shift keys, so the program delays that decision until the user does something else, like releasing the button or moving the mouse.

If you want your programs to be user-friendly, you have to pay attention to details. It may require a lot of work to make a process intuitive for the user. Even things we take for granted, like multiple selection, require a lot of thought, and a lot of work. It's easy to avoid that extra effort - at the end of the day, most users won't even notice these features. But they will use them, and they will notice if they're missing. and they might even look for alternatives to your program.

|

Setting body tag attributes in code
Sunday, October 10, 2004 01:46 AM

Here's something that's obvious once you already know how to do it. If you don't, however, it could take a while to figure this out.

In ASP.NET, when you place controls on a web page, they have corresponding fields in the page object. These fields allow you to access and manipulate the controls in your code. Simple HTML elements, however, don't have corresponding objects - they only exist in the .aspx file. The <body> tag is one of these elements.

It turns out you can create objects that correspond to simple HTML elements, and modify these elements by setting properties in code. There are three things you have to do:

  • First, make sure the tag you want to edit has an ID, so you can call it by name. To set the ID for the <body> tag, either edit the .aspx file directly, or set the id property of the document element in the IDE (in Delphi 8, for example, open the combo box at the top of the Object Inspector, and select "DOCUMENT"). For example:

<body id=MainBody ms_positioning="FlowLayout">

  • Second, add the runat attribute to the tag and set it to "server". This is the crucial part. If you don't do that, the page object will have no knowledge of the tag and all attempts to access it as an object will result in an exception. You have to do this manually, though, by editing the .aspx file.

<body id=MainBody ms_positioning="FlowLayout" runat="server">

TWebForm1 = class(System.Web.UI.Page)
{$REGION 'Designer Managed Code'}
strict private
  procedure InitializeComponent;
{$ENDREGION}
strict private
  procedure Page_Load(sender: System.Object; e: System.EventArgs);
strict protected
  MainBody: HtmlGenericControl;
  procedure OnInit(e: EventArgs); override;
end;

Now you can use the field to manipulate the actual HTML. For example, I needed to change the page's direction based on the language selected by the user:

procedure TWebForm1.Page_Load(sender: System.Object; e: System.EventArgs);
begin
  if Request.Params['lang'] = 'hebrew' then
    MainBody.Attributes['dir'] := 'rtl'
  else
    MainBody.Attributes['dir'] := 'ltr';
end;

|

New ASP.NET vulnerability
Wednesday, October 06, 2004 10:29 AM

Microsoft just published some information about a new ASP.NET vulnerability. According to the web page, an attacker could exploit this vulnerability to view secured content on a server without providing the proper credentials. This issue affects any version of ASP.NET.

At the moment, Microsoft recommends implementing the suggestion made in KB article 887459 ("Programmatically Checking for Canonicalization Issues with ASP.NET"). The article provides C# and VB.NET code samples. If you're using Delphi 8, open the Global.pas file and edit the Application_BeginRequest method:

procedure TGlobal.Application_BeginRequest(sender: System.Object; e: EventArgs);
begin
  if (Request.Path.IndexOf('\') >= 0) or
    (System.IO.Path.GetFullPath(Request.PhysicalPath) <> Request.PhysicalPath) then
    raise HttpException.Create(404, 'not found');
end;

Make sure you add System.IO to your uses clause to compile the code.

|

Pilot projects
Sunday, October 03, 2004 01:52 PM

That remarkable book, Peopleware, defines a pilot project as "one in which you set the fat book of standards aside and try some new and unproven technique." The book discusses some of the pros and cons of pilot projects, but focuses mainly on their effects on development teams. In recent years, I have been working mostly as an independent consultant, and while not all the concepts illustrated in the Peopleware discussion of pilot projects apply to one-person shops, I have found pilots to be extremely beneficial even to a single developer. Read more...

|

Diamondback information
Saturday, October 02, 2004 01:54 PM

As I mentioned in my BorCon posts, Borland is being very open about the technical aspects of Diamondback, the next version of Delphi. A lot of information is already available on BDN:

The R&D engineers are also blogging about Diamondback:

If you attended BorCon and got your Diamondback preview CD, you can now talk about it, write about it, and show it. I showed a quick demonstration of Diamondback to one of my clients (currently using Delphi 8), and they were amazed. I showed a glimpse of about 10% of what's new, and they told me that's more than enough for a new major version. They could hardly believe there was more.

|

More on gummy bears
Saturday, October 02, 2004 11:36 AM

I don't know why the PETA people aren't on this - it seems unfair that scientific experiments should be tolerated on gummy bears just because they're, well, gummy:

"In all cases, E. coli was transferred from the tile to the food, demonstrating that microorganisms can be transferred from ceramic tile to food in 5 seconds or less. More E. coli were transferred to gummy bears from smooth tiles than from rough tiles."

- University of Illinois College of Agricultural, Consumer and Environmental Sciences

Jillian Clarke of the Chicago High School for Agricultural Sciences has been awarded the prestigious Ig Nobel prize in Public Health for this scientific investigation of the Five-Second Rule about whether it's safe to eat food that's been dropped on the floor.

|

Copyright 2004 Yorai Aminov