Google Search

Tuesday, April 28, 2009

What can the government of Israel do to solve the water crisis

Israel suffers greatly from lack of water.

This is the case for many years now, and from one year to another the government is doing more and more to solve it. By "doing more and more" I mean pass on the blame and the responsibility to the citizens.

Now they have a big campaign featuring all greatest Israeli celebrities, telling us to save water; telling that we must stop watering our gardens; asking to shower less. Before we'll know it they'll limit our tap water drinking.

This is, of course, useless and idiotic. It won't help even a tiny bit. This is the same as doing micro-optimization to a monkey-sort algorithm. This is because the reason to this water crisis lies mainly on the fact that the population growing while the amount of water in our reservoirs stays the same (in the good case) or lowers (in the bad, current, case).

Saturday, April 25, 2009

BiDi – What is it, why we need it

BiDi stands for Bi-Directional text. Yes, specifically text. In some places (such as the Word text editor) this is referred to as Complex Scripts.

So what exactly is it? It is the case where several languages of different writing directions are mixed in a single sentence. More than that, in some cases, this is the case where a Right-To-Left language (Hebrew, Arabic and Persian) needs to be rendered to screen.

Why is this a problem? This is a problem because there is a dilemma of how to store textual data that contains both directions of writing; On the one hand, it can be stored visually, just like it appears on the screen. It will make it much easier to render, and save us from all the burden and improve performance of the rendering phase. On the other hand, however, it will make our writing phase much harder, and will require us to write some of the text reversed. Actually this is exactly what people where doing before the age of Logical Text and the BiDi algorithm.

The BiDi algorithm brought a new age of Logical Text, and by that we mean the way the text is stored in memory. Instead of storing it the way it is rendered, we store it the way it is being read and written. When we read text that contains several text directions (Hebrew and English mixed, for example), we change our reading direction every time the language is changed. When we write text that contains several directions, we still write the first letters first, and last letters last, even when the language changes. We don’t reverse the order of characters for that task.

A quick review of different UI frameworks

In this post I'll review several frameworks used for creating graphical user interfaces. I've decided to create such a review after noticing many programmers take a specific GUI framework for granted, as it is their automatic-choice-by-tool (i.e., they use what they're IDE let them, barely understanding the layers required to develop such a framework, and that there are alternatives they might have chosen if they had knew about).

I will review the following frameworks:

  • Windows.Forms
  • WPF (+Silverlight)
  • GTK
  • QT
  • wxWidgets
  • AWT
  • Swing
  • SWT
  • X/XT/Motif

Wednesday, April 15, 2009

Runtime testing and casting objects of generic types

How can you tell, in runtime, if an object you have is of a specific generic type? For instance, if it implements the generic interface ICollection ?

You might say, "lets get all interfaces implemented by that object, first by getting its type (using GetType()), then by calling GetInterface(string name), passing in the type name in its mangled form".
This will work, however, this yields to error prone, non-type-safe code, plus, making us required to know how to build the relevant mangled string.

We would like something better. We would like to be able to get the generic type itself. Fortunately this can be easily done the following way:
Type genericCollectionInterfaceType = typeof(ICollection<>);

This will return the generic collection interface type. Now, what can we do with it? We wanted to test if a certain object implements this interface. However, a list of, say, strings, will NOT implement that interface. It will implement the ICollection<String> interface, which is not the same as ICollection<>.

What can we do? We need to build, in runtime, a generic interface type that corresponds to the interface signature of our object:
Type testedObjectType = testedObject.GetType();
Type genericType = typeof(ICollection<>).MakeGenericType(testedObjectType.GetGenericArguments());

Then we can use that type to test for assignability:
collectionType.IsAssignableFrom(testedObjectType);

Calling MakeGenericType creates a new Type object that represents the type we are looking for. We pass it a list of types, in this case taken from the object itself (using GetGenericArguments). Then we can check for assignability between the two.

kick it on DotNetKicks.com

Saturday, April 11, 2009

Lasers and experiments

I tried to activate a laser diode today, that I disassembled from an old DVD player.
I used a cellphone recharger (outputs 5V) and connected the wires.
It worked for about half a second. I think it is now dead. R.I.P.
Anyone got old DVD/Bluray players they don't need?

The dead laser diode (on the right), and its original housing and controller.


The disassembled DVD player.

Thursday, April 9, 2009

Creating customizable WPF drop-down menus (7)


Step 7: Using the new binding correctly


Remember that we overridden OnDragEnter so the menu will open upon hovering? Well, we will have to make a slight change to that code, to (also) use our new property:

protected override void OnDragEnter(DragEventArgs e)
{
    IsSubmenuOpen = true;
    IsSubmenuOpenInternal = true;
    e.Handled = true;
}

Great! Except now the menu never closes. Well, the first occasion we want it to close is when we're done dropping. So we will add the following snippet to our OnDrop code, just before the e.Handle = true code:
if (parentMenuItem != null)
    parentMenuItem.IsSubmenuOpenInternal = false;

Another case when we want it to close is whenever a neighbor menu opens, or in case we stopped using the menu at all (like, clicking any other place). But the thing is, we really don't want to write such code, as it is already written. We need a way to find when the original property would change to false and do the same.
Luckily, there is a routed event just for that: SubmenuClosed.
We will register to that event, and change our new property to false likewise. Except, we do it with a minor change: we need to make sure we are not in the middle of a drag operation, or right in the drop handling code. We will register to that event in the constructor, and implement it:
public DraggableMenuItem()
{
    AllowDrop = true;
    SubmenuClosed += new RoutedEventHandler(DraggableMenuItem_SubmenuClosed);
}

void DraggableMenuItem_SubmenuClosed(object sender, RoutedEventArgs e)
{
    if (Mouse.LeftButton == MouseButtonState.Pressed || !IsDragging)
        IsSubmenuOpenInternal = false;
}

But now there is another problem - the menu doesn't open well, since we replaced the IsSubmenuOpen with IsSubmenuOpenInternal. So the same way, we need to handle the open event - SubmenuOpened:
public DraggableMenuItem()
{
    AllowDrop = true;
    SubmenuClosed += new RoutedEventHandler(DraggableMenuItem_SubmenuClosed);
    SubmenuOpened += new RoutedEventHandler(DraggableMenuItem_SubmenuOpened);
}

void DraggableMenuItem_SubmenuOpened(object sender, RoutedEventArgs e)
{
    IsSubmenuOpenInternal = true;
}

And that's it! The menu is now Drag-and-Drop customizable! Note that the code brought here in this article is for explanatory purposes only, and is far from perfect. Its goal is to explain the main issues and problems encountered while developing such a control, so use it as a reference only.

Hope you have found it useful, and please let me know if you did, and I'll be glad to hear about successful (preferably complete) implementations.

Creating customizable WPF drop-down menus (6)


Why dropping doesn't work on sub-menus?


This question is actually the heart of the entire process. All we did until now was quite straight-forward.
So, why doesn't it work? To solve that I tried several debugging methods, but the one that really got me somewhere was to enable Reference Code Debugging.
So I found myself debugging deep into the WPF code, finding that during the drop operation, the result of the hit-test being performed is actually 'null'(!). More than that, it seemed like the native window holding the sub-menu wasn't even there (!!). How can that be?
Well, I couldn't debug much deeper than that, but thinking about how drop-down menus work, and how drag-and-drop mechanisms work, I figured that the problem must be that the sub-menu popup was closing before the drop operation hit test takes place.

This means that if I want to be able to drop things on a sub-menu, I need to build a new mechanism that will keep it open until AFTER the drop.

Step 6: Keeping the sub-menu open


Now it is going to get clear why I insisted on inheriting MenuItem (and be sure it will get worse, as we will need to change the default control template).

We will need to introduce a new Dependency Property that will enable us to better control whenever the sub-menu is open. Let's call this property IsSubmenuOpenInternal:
public static readonly DependencyProperty IsSubmenuOpenInternalProperty =
   DependencyProperty.Register("IsSubmenuOpenInternal",
                               typeof(bool), typeof(DraggableMenuItem),
                               new FrameworkPropertyMetadata(false));

public bool IsSubmenuOpenInternal
{
   get { return(bool)GetValue(IsSubmenuOpenInternalProperty); }
   set { SetValue(IsSubmenuOpenInternalProperty, value); }
}

In the XAML code, we will change the default style (this can be easily done using "Expression Blend") so the sub-menu opening state will now bind to our new property, rather than the default one.

I will not place here the entire XAML for the new menu item class, since it is just too long.
What you will need to do is to use Expression Blend to copy the default MenuItem style, then make the following changes:
  • Change the TargetType attribute to our new class type. Remember to add the relevant namespace declaration in the XAML declaration.
  • Locate the Popup element block, and change its IsOpen binding from IsSubmenuOpen to our new IsSubmenuOpenInternal dependency property.



Important Note:
If I could, I would of course rather override the default IsSubmenuOpen property, leaving the XAML as it is. However, this is impossible (at least in accepted methods, without using reflection), so adding this property really seems like the only way to go.


Now that the new bindings are in place, we can move on to the next post :-)

Monday, April 6, 2009

Creating customizable WPF drop-down menus (4,5)


Step 4: Responding to drag hovering


Important Note:
In this part of the tutorial, we implement the draggable menu items that are static, and still in the menu, rather then the one being dragged. Keep that in mind, this is important.

We want our menus open whenever an item is dragged over them. The simplest solution would be to override the OnDragEnter method, and set the IsSubmenuOpen property to true.
This will work for now, but we will have to change that later, when we get to the drop-handling part.
Anyway, for now:
protected override void OnDragEnter(DragEventArgs e)
{
    IsSubmenuOpen = true;
    e.Handled = true;
}

Step 5: Handling drops


First we must accept drops. Lets implement the constructor:
public DraggableMenuItem()
{
    AllowDrop = true;
}

This code snippet set our draggable menu item to accept drops. Without this, it wouldn't be possible to drop anything on it, so we wouldn't be able to customize our menu.
Next we need to catch the drop operation, and perform the item movement logic. Of course we shall override and implement OnDrop. Note that we will need to extract the item being dragged from the DragEventArgs, and if it is a DraggableMenuItem, remove it from its current position, and place it just before the drop target:
protected override void OnDrop(DragEventArgs e)
{
    DraggableMenuItem draggedItem = (DraggableMenuItem)e.Data.GetData(typeof(DraggableMenuItem));
    DraggableMenuItem parentMenuItem = Parent as DraggableMenuItem;
    Menu parentMenu = Parent as Menu;
    ItemsControl itemsControl = Parent as ItemsControl;
    if (draggedItem != null && (parentMenuItem != null || parentMenu != null)) 
    {
        int i = itemsControl.Items.IndexOf(this);
        ItemsControl draggedItemParent = draggedItem.Parent as ItemsControl;
        if (draggedItemParent != null) 
        {
            draggedItemParent.Items.Remove(draggedItem);
        }
        itemsControl.Items.Insert(i, draggedItem);
        e.Handled = true;
    }
    base.OnDrop(e);
}

First attempt to test it all


Generally, while things don't look as nice as they can be, and might still be somewhat buggy, it looks like things should work.
Testing it reveals that dropping items on the menu bar level does work. However, dropping things on open sub-menus doesn't!
I will review the reason for that on the next post.

Creating customizable WPF drop-down menus (3)


Step 3: Dragging items around


Once we have figured out how to detect the drag, we need to perform the actual dragging. Moreover, we want the menu to respond while we move around - hovering over a menu should cause it sub menu (if any) to open.

We will use the System.Windows.DragDrop helper class to perform the actual dragging.
The main method in the DragDrop class is DoDragDrop. This method is used to initialize a drag-and-drop session, perform the actual drag-and-drop operations, and returns the effect.

Initializing a drag-and-drop session


The DoDragDrop method takes 3 parameters:
  • A drag source (which will be our draggable menu item),
  • A data object, and
  • The allowed effects.

So as I mentioned, the drag source will be our draggable menu item. Since the code will be written as part of that menu item, we will just place there 'this'.
Our data source, while can be anything at all (as it is of type object), should be of type System.Windows.IDataObject, since otherwise it will be wrapped with a DataObject.
The best thing to do in this case would be to create a DataObject, and give it a unique name (or type), and the data itself. In our case, the data is the draggable menu item we'll be dragging, so the best unique id would be its type.
The only allowed effect, in our case, is the move effect, as this is what we want to do (at least for now) - move menu items from one place to another.

So if we implement the DoDragging method we left empty before:
private void DoDragging()
{
    IsDragging = true;
    DataObject dataObj = new DataObject(typeof(DraggableMenuItem), this);
    DragDrop.DoDragDrop(this, dataObj, DragDropEffects.Move);
    IsDragging = false;
}

Note that I raise the IsDragging flag before the dragging process begins, and lower it immediately afterwards. One reason for that is to prevent dragging to begin on other draggable menu items. Other reasons will become clear in the following posts.

Creating customizable WPF drop-down menus (2)


Step 2: Detecting drag


Drag will start when the user had pressed the mouse button on an item and moved it enough distance in pixels while being pressed.
So, we need to know where the mouse was pressed, then track it all time it is pressed until it moves far enough:
public class DraggableMenuItem : MenuItem
{
    private Point m_dragStartPoint;

    public static  bool IsDragging { get; set; }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        m_dragStartPoint = e.GetPosition(this);
        base.OnMouseLeftButtonDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (e.LeftButton != MouseButtonState.Pressed || IsDragging)
            return;

        Point p = e.GetPosition(this);
        if (Point.Subtract(m_dragStartPoint, p).LengthSquared < 16)
        {
            e.Handled = true;
            return;
        }

        DoDragging();
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        IsDragging = false;
        base.OnMouseLeftButtonUp(e);
    }

    private void DoDragging()
    {
    }
}
Note that the IsDragging flag is a static flag, thus shared among all instances of the DraggableMenuItem. In the code sample above we do not yet assign it. This will be done in the next steps, in addition to some other places we will need to use its value to achieve the correct behavior.

Thursday, April 2, 2009

Code Snippets (2)

After I couldn't find a decent way to implement nice, colorful code snippets inside blogger (which holds me back from posing code related articles) as I mentioned in my last post, and after checking "CopySourceAsHtml" as suggested by Asher in his comment to my last post (and didn't like it - it creates HTML I really don't want to use), I decided to go on with writing my own converter.
I used the GOLD parsing system, along with the Calitha gold parser engine to parse source code of a given grammar (grammars for GOLD can be found here), added some metadata to that grammar (currently I've only done a proof-of-concept, so everything is hard-coded) that defines how to indent and colorize (HTMLize) it, and wrote this application:

(click to enlarge)

Next will probably be adding another language (C# - currently only tried it with XML), extracting metadata to external files (should see if I can merge it with the GOLD parser grammar files, and read it from there somehow), and making things look nicer, for starters.

The code is currently not available for download, but I'll probably start a project on sourceforge for that soon. I'll post an update when I will.