Thursday
Jun132013

Interlude: Real Computer Monster  

Wednesday
Jun122013

Making Mischief - The Newest Tool for High Resolution Artwork  

Just go ahead and instill the trial edition of Mischief by 61 Solutions.

Speed? off-the-charts and as you watch the video below you will see exactly why this is amazing.

Interesting features? 50 Trillion to 1 zoom. What?

And it's vector-based!

Sunday
Jun022013

UX: Over-sensitivity in Two-Level Flyout Menus  

This is an issue you'll find often in web sites. Let's take the Vimeo music store (http://vimeo.com/musicstore) where this morning I was reminded of this problems

Snap00034

 

Specifically I'm going to the Search box and look for “Chill out music”. Now just clicking on the search box, reverals the flyout, conveniently for me I see that it is a classic two-level flyout meny. The first level is a category. In this example, it is set to “Genre” and the seccond level a list of items in the category. Fortunately for me, “Chill-out” is already listed (highlighted in red below).

Let's see what happens: 

 

 Animation1a

And now the breakdown: I click on the search boc and see “Chill-Out”

Snap00035-a

 

Naturally intend I move my mouse as shown below.

Snap00035-b

As my cursor crosses the first level of the flyout –  it selects another category.

Snap00036

Now keep in mind I'm not slowly moving the cursor –  I'm making a very fast gesture that will bring the cursor to my destination in a fraction of a second.

The end result is that I have find my mouse where “Chill-out” used to exist on my screen.

Snap00037

This is an irritating pattern because, once a user figures this out they have to carecfully navigate the maze of the flyout as shown below:

Snap00038

 

A couple of things I want you to keep in mind.

  • Depending on the UI, the maze can get tricky to navigaste as you may have to move the mouse down some tight corridors. For example if “Genre”s had been an icon only that corridor may have been very small.
  • Users may not have the physical dexterity to do this –  they have problems moving their hands and so their paths may be more erratic than very precise geometric movements
  • Some users may be using a device that makes such fine control difficult
  • Users may be able to perform the navigation, but it may take time doing it due to their device or physical dexterity

 

Possible solutions

  • One option is to provide a delay when moving over the first category. The problem there is that for some people the delay will not be enough and also other people will perceive the delay as sluggishness.
  • The most straightforeward solution is force users to click on the category to select it instead of relying on merely cursor position.

 

 

 

Friday
May312013

Using C# To Draw An OrgChart in Visio 2010  

I added a new sample to my NuGet package Visio C# Samples. It's a very straightforward sample of how to draw an org chart.

Some of the things it demonstrates

  • How to open a template-based visio document (such as an org chart)
  • Using the DropManyU API
  • Using the AutoConnect API
  • How to detect which version of Visio is being used

Notes:

  • The code works for both VIsio 2010 and Visio 2013.
  • Auto-positioning of the shapes is NOT covered. That is a separate problem I didn't want to cover in this example.

The code is shown below:

 

            var app = new IVisio.ApplicationClass();
            var docs = app.Documents;

            // Create a new OrgChart using the org chart template
            var doc = docs.AddEx("orgch_u.vst", IVisio.VisMeasurementSystem.visMSUS, 0,0);
            var page = app.ActivePage;

            // Get the masters
            bool is_visio_2013 = app.Version.StartsWith("15.");
            var orgchart_masters = doc.Masters;
            var position_master = orgchart_masters[is_visio_2013 ? "Position Belt" : "Position"];
            var dyncon = orgchart_masters["Dynamic Connector"];

            // three masters to drop
            var masters = new object[] { position_master, position_master, position_master };

            // three coordinates to make the drop
            var xy_array = new double[] {1,2 ,3,5, 6,2};

            // perform the drop of all shapes at once
            // and get the shape ids back out
            System.Array shape_ids_sa;
            page.DropManyU(masters, xy_array, out shape_ids_sa);
            var shape_ids = (short[])shape_ids_sa;

            // using the shape ids, get the shape objects
            var shape0 = page.Shapes.ItemFromID16[shape_ids[0]];
            var shape1 = page.Shapes.ItemFromID16[shape_ids[1]];
            var shape2 = page.Shapes.ItemFromID16[shape_ids[2]];

            // perform connections using the Dynamic Connection master
            shape0.AutoConnect(shape1, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
            shape1.AutoConnect(shape2, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);

 

Sunday
May262013

Returning Collections from Functions in PowerShell: A tip for C# Developers learning PowerShell  

Back in April mentioned something C# developers should pay attention to as they start writing PowerShell code. Following the spirit of that post, I want share another common behavior which will be very confusing and offer a solution.

 

Let's start with this code:

 

$a = New-Object 'System.Collections.Generic.List[string]'

$a.Add("A")

$a.Add("B")

$a.Add("C")

$a.GetType().Name

 

What do you think will be printed? If you said a the type name for List<string> you are correct –  although it gets printed in a very ugly way:

 

List`1

 

Ok, let's try another case

$table = New-Object system.Data.DataTable

$col1 = $table.Columns.Add( "Col1", [string])

$col2 = $table.Columns.Add( "Col2", [int])

$table.Rows.Add( "bar", 0 )

$table.Rows.Add( "beer", 1 )

$table.Rows.Add( "baz", 2 )

$table.GetType().Name

 

Here's what (unsurprisingly) gets printed:

 

DataTable

 

Using Functions

Now let's put that same code into functions:

 

function f1()

{

    $arr = New-Object 'System.Collections.Generic.List[string]'

    $arr.Add("A")

    $arr.Add("B")

    $arr.Add("C")

    return $arr

}

 

function f2()

{

    $table = New-Object system.Data.DataTable

    $col1 = $table.Columns.Add( "Col1", [string]) | Out-Null

    $col2 = $table.Columns.Add( "Col2", [int]) | Out-Null

    $table.Rows.Add( "bar", 0 ) | Out-Null

    $table.Rows.Add( "beer", 1 ) | Out-Null

    $table.Rows.Add( "baz", 2 ) | Out-Null

    return $table

}

 

And now lets call those functions and check the return type

$a = f1

$a.GetType().Name

$t = f2

$t.GetType().Name

 

Here's what we expected to get printed

 

List`1

DataTable

 

Here's what we actually get:

 

Object[]

Object[]

 

What happened?

If you come from a C# background this is surprising. All I can say is that you have to remember that PowerShell doesn't always follow the semantics and behavior we are used to. In this case, when a PowerShell function detects that you are retuning a enumerable object (such as a collection), it places each member of the collection on the pipeline as a separate item.

 

The Solution

This is going to look ugly, but the way to get around this is to return your collections as a single element array. The code below shows exactly how:

 

function f1()

{

    $arr = New-Object 'System.Collections.Generic.List[string]'

    $arr.Add("A")

    $arr.Add("B")

    $arr.Add("C")

    return @(,$arr)

}

function f2()

{

    $table = New-Object system.Data.DataTable

    $col1 = $table.Columns.Add( "Col1", [string]) | Out-Null

    $col2 = $table.Columns.Add( "Col2", [int]) | Out-Null

    $table.Rows.Add( "bar", 0 ) | Out-Null

    $table.Rows.Add( "beer", 1 ) | Out-Null

    $table.Rows.Add( "baz", 2 ) | Out-Null

    return @(,$table)

}