Saturday 18 January 2014

Deploying local Nodejs git repo to Heroku, what to remember about?

A short summary on deploying local code using git to heroku, which requires a fair bit of googling  every time I'm attempting it. All we need to do after we've got our code working locally with all the packages we required installed.
  1. heroku create appname - creates a heroku app with a given name ( if not explicitly stated it's gonna get randomized )
  2. git remote -v - will show us whether the remote was successfully created for our local repo.
  3. create a procfile, which describes what types of processes are gonna be launched on Heroku in my case (a web server) the inside of the files were as follows:

    web: node name_of_the_node_server_file.js

  4. Create a package.json file which contains information about the app, especially the packages info, and launching script. In my case it looked like that:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {
      "name": "AppName",
      "version": "0.0.1",  
      "description": "Description",
      "main": "name_of_the_server_file.js",
      "dependencies": {
     "connect": "x.x.x",
     "util": "x.x.x"
      },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node name_of_the_server_file.js"
      },
      "repository": {
        "type": "git",
        "url": "https://bitbucket_login@bitbucket.org/bitbucket_login/repo_name.git"
      },
      "author": "Name"
    }
    


  5. We need to add these files and use a standard git commit
  6. git push heroku master - where heroku is a remote created by "heroku create".
  7. Now we can open our app on heroku.
  8. In case of errors we can check the logs from the server through command line:

    heroku logs 
Helpful links:

         Deploying to Heroku with git - https://devcenter.heroku.com/articles/git
         Heroku logs - https://devcenter.heroku.com/articles/logging
         Procfile types - https://devcenter.heroku.com/articles/procfile


Friday 10 January 2014

Hooking up a new git repository to bitbucket

I always forget one of the steps and end up googling. That's why I'll leave this little list here to have a safety net next time I'm connecting my local repo to bitbucket.
  1. Created repository folder with a file inside inside. Something like:  /Repositories/NewRepo/helloworld.txt

  2. Open console inside of the NewRepo folder. It initiates a new git repository in the NewRepo folder:       git init

  3. We're adding the file (proposing the changes) by using:
        git add helloworld.txt
                                or
        git add *

  4. To commit the changes we use:
        git commit -m "Adding helloworld.txt"

  5. We create a repository in https://bitbucket.org/ by clicking "Create Repository" button and just filling out the form. We end up having bitbucket repository called: BitbucketLogin/reponame. Lets say our reponame is also NewRepo.

    We need to add a remote to the bitbucket repository:
    git remote add origin       https:/BitbucketLogin@bitbucket.org/BitbucketLogin/oureponame.git

    In case we're trying to commit to someone else's repo, we should use:
    git remote add origin https:/OurLogin@bitbucket.org/SomeonesLogin/soomeoneseponame.git

  6. If we made a typo in the above, we can remove the remote and add it again:
    git remote rm origin

  7. All that is left is to push the changes to bitbucket:
    git push origin master

Sunday 5 January 2014

Adding Drag and drop behaviour to ItemsControls Part 3

        Third part of the drag and drop tutorial in WPF. I'll start with the mouse move event and checking whether anything is being dragged.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
private static void OnMouseMove(object sender, MouseEventArgs e)
{
    ItemsControl source = (ItemsControl)sender;

    System.Windows.Point currentPos = e.GetPosition(null);
    Vector diff = startPoint - currentPos;

    if (e.LeftButton == MouseButtonState.Pressed &&
       ( Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
         Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
    {                
        object data = GetDataFromSource(source, e.GetPosition(source));

        if (data != null)
        {
            DragDrop.DoDragDrop(source as DependencyObject, data, DragDropEffects.Move);
        }                
    }
}

         Above handler uses GetDataFromSource method for retrieving the dragged data from the source control. The method finds the UIElement that has been clicked, checks in the loop, if the item is indeed in the ItemsControl collection and generates adequate dto that is gonna be transferred between collections. In case the SourceControl is reached in the loop it means that the particular item has not been found.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
private static object GetDataFromSource(ItemsControl source, System.Windows.Point point)
{
    UIElement element = source.InputHitTest(point) as UIElement;

    if (element != null)
    {   
        object data = DependencyProperty.UnsetValue;
        while (data == DependencyProperty.UnsetValue)
        {
            element = VisualTreeHelper.GetParent(element) as UIElement;
            if (element == source)                    
                return null;
            
            data = source.ItemContainerGenerator.ItemFromContainer(element);            
        }

        if (data != DependencyProperty.UnsetValue)                
            return data;                
    }
    return null;
}

        Then comes the method for handling drop events, we need to take notice of several special cases, most are commented the rest self explanatory.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private static void Drop(object sender, DragEventArgs e)
{
    ItemsControl parent = (ItemsControl)sender;

    // Checking if there's a group that has control assigned to it
    if (!dragSources[GetGroupName(parent as DependencyObject)].Any(p => p == parent))
        return;
    
    // Get the type of data that's used for the object transfered between containers
    var dataType = parent.ItemsSource.GetType().GetGenericArguments().Single(); 
    // Aquiring data of the particular type
    var data = e.Data.GetData(dataType);                                        

    // This will hit when we'll try to drop garbage into the container
    if (data == null)   
        return;

    // We don't wanna drop the same data to the same control again
    if (((IList)parent.ItemsSource).Contains(data)) 
        return;

    var foundControl = dragSources[GetGroupName(parent as DependencyObject)]
        .Find(p => ((IList)p.ItemsSource).Contains(data));

    if (foundControl == null)
        return;

    ((IList)foundControl.ItemsSource).Remove(data);
    ((IList)parent.ItemsSource).Add(data);
    BindingOperations.GetBindingExpressionBase(parent as DependencyObject, 
        ItemsControl.ItemsSourceProperty).UpdateTarget();
    BindingOperations.GetBindingExpressionBase(foundControl as DependencyObject,
        ItemsControl.ItemsSourceProperty).UpdateTarget();
}

        Last thing left is to add the code for several more handlers we've already used in the previous post. Except for the OnLeftButtonDown, they are all used to prepare the container as a drag and drop container after it becomes visible to the user and remove it from the drag and drop mechanism when it is being hidden from the user. Hence every time the window with such container is being brought forth all adorned ItemsControls are being added to the behaviour and removed when for instance the window containing them hides.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private static void OnLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    startPoint = e.GetPosition(null);
}

private static void DragSource_Loaded(object sender, RoutedEventArgs e)
{
    Add(dragSources, sender);
}

private static void DragSource_Unloaded(object sender, RoutedEventArgs e)
{
    Remove(dragSources, sender);
}

private static void DropTarget_Loaded(object sender, RoutedEventArgs e)
{
    Add(dropTargets, sender);
}

private static void DropTarget_Unloaded(object sender, RoutedEventArgs e)
{
    Remove(dropTargets, sender);
}

       The last handler is the one servicing the drag and drop group name changes, in case the group name is bound to something that changes it during run time. If that happens we need to switch the ItemsControl drag and drop container to a different group.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
private static void GroupNameUpdated(DependencyObject dp, DependencyPropertyChangedEventArgs args)
{
    var itemsControl = dp as ItemsControl;
    string newGroupName = (string)args.NewValue;

    InitializeDragDropCollections();

    if (!dragSources.Any(p => p.Key == newGroupName))
        dragSources.Add((String)args.NewValue, new List<ItemsControl>());
    if (!dropTargets.Any(p => p.Key == newGroupName))
        dropTargets.Add((String)args.NewValue, new List<ItemsControl>());

    var foundCollection = dragSources.Where(p => p.Value.Any(k => k == itemsControl) == true);
    if (foundCollection != null && foundCollection.Count() > 0)
    {
        foundCollection.First().Value.Remove(itemsControl);
        if (!dragSources[((String)args.NewValue)].Any(p => p == itemsControl))
            dragSources[((String)args.NewValue)].Add(itemsControl);
    }            
}

       If you'd like to get the whole code I added the class to my github account:
       http://github.com/simonkatanski/WpfDragAndDropBehavior.git