Montag, 6. Mai 2013

Windows Presentation Foundation: Getting started

I am new to WPF, so I gathered some readin material which helped me get started. If you too are new to WPF, then I can highly recommend the following articles...
I hope that'll help &enjoy the read ;) !

Here are some more general tutorials about design etc related to WPF:

Adding a global Exception-Handler to a WPF project

After a long C# absence, I am once more working on a project written using WPF and Visual Studio 2010. I am still busy getting the hang of it, so I'll document some discoveries along the way.

In Android you can implement your own UncaughtExceptionHandler, which comes in handy, if you need to add final log messages to the log, before your app goes south ;) .

So I was wondering how to do the same or at least something similar in WPF. This site documents how to use DispatcherUnhandledException Event. For the sake of completeness (and if the above link is ever deprecated), here is one code snippet to do the job:

// Application
using System.Windows; 
// DispatcherUnhandledExceptionEventArgs 

using System.Windows.Threading;

namespace MyProject
{


public partial class App : Application {

        public App(){ }

        protected override void OnStartup(StartupEventArgs e)
        {
            Application.Current.DispatcherUnhandledException 

            += new DispatcherUnhandledExceptionEventHandler 
            (OnUnhandledExceptionCaught);

            base.OnStartup(e);
        }

        void OnUnhandledExceptionCaught(object sender, 

         DispatcherUnhandledExceptionEventArgs args)
        {
          //Do whatever you need to
        }
    }
}


However this is not the only option, there is an easier one as well:

In your App.xaml (the xaml file for your application class), add the following attribute (marked in bold) to your Application element (also added for structural clarification):

<Application ....
  DispatcherUnhandledException="OnUnhandledExceptionCaught">
  ...
</Application>

Now add the implementation of OnUnhandledExceptionCaught from the first snippet, but omit the manual adding of the handler in the OnStartup method and you're all set! I presonally prefer this option to the first one.

Sonntag, 28. April 2013

How to color a drawing (and how not to freak out on Gimp)

Gimp - a free image editing tool almost made me throw my PC out of the window in the past few days. The reason: It was paaainfully slow and crashed numerous times, while I was editing an image with roughly 5000x6000 pixel. My PC is most certainly not at fault, since it's very well equipped and running a 64Bit Version of Windows 7. Gimp however is a 32 Bit application, so there might be an issue.

Either way, due to the problems I kept having with Gimp I split my image editing between two applications:
  • Gimp for drawing the outline
  • Paint.Net for the base coloring
  • Gimp for finishing touches/effects
Turned out that was a great idea, as the coloring (which had been horribly slow and awkward with Gimp) was a breeze in Paint .Net. The latter however did not have the tools I needed for the effects and finishing touches, so this is where Gimp came in again.

Here is a mored detailed description of the separate steps (all images have been downsized so the upload sizes moves within reasonable ranges):

1. Draw your image with a pencil ;)

2. Scan your image as high res as possible, although 600dpi seems to be more than enough, anything beyond that, is possibly gonna kill Gimp...

The scanned image looked like this (I used a ballpoint to re-draw the pencil lines before scanning)


3. Open the scanned image, add another layer with an invisible background. On that layer I then re-drew the outlines using the Path tool and a soft brush I had created for that purpse. Here are the brush settings:

  • Radius - however thick you need the line to be (I used 2 but later switched to 5)
  • Spikes 2
  • Hardness 0.78
  • Aspect Ratio 1
  • Angle 0
  • Spacing 20
Once you've re-drawn the complete outline, delete the background layer and you should
now have an invisible layer with the black outline on it. Save it as a PNG file. The result looks something like this:


4. Now we'll switch to Paint.Net for the coloring. Open the previously saved PNG file into Paint.Net, duplicate the layer, and use the lower layer for the coloring. This way you can draw over over/on the outlines, which will be preserved, through the second outline layer on top of the layer we're coloring.

Now you can simply use your paint bucket and color all the areas you want. Don't bother introducing shadows yet or effects, we'll do this later with Gimp. This is how the base coloring looked:

5. Back to Gimp and we're almost done.  The base coloring looks a little flat, so I'll use Gimp's Paintbrush and the Path tool to create some shadows. First of all you'll have to open the previously saved PNG file in Gimp. no messing the the layers this time. First of all, take the magic wand and select the outline (black). Then in the Menu bar click on Select - Invert. This way we'll invert the selection and will have everything selected, except the outline. This way we'll ensure, that the outline is safe from unwanted modification (drawing over etc).

Now makre sure to not lose that selection or you'll have to re-select everything. To create shadows I mostly used the Path tool, the Paintbrush was only used when I had to fill bigger areas, alternatively the Paint Bucket tool could be used for that as well.

As for the colors: Use the color picker tool, to select the color of the area you want to create shadows for. Then manually set the color a bit darker/stronger. Next thing we'll have to adjust our brush settings. We'll also use those Brush settings to stroke the paths. The settings are based on the previously created Brush (see above):
  • Mode - Darken only (this is the most important thing!)
  • Size 40
  • Aspect Ratio 0
  • Angle 0
  • Dynamics - Basic Dynamics
  • Fade Options - Fade Length 100
  • Color options - Gradient FG to Transparent
Now carefully crafting those shadows will take a while and eventually it'll make the image look less flat. Here is the final result:

 
This is the scaled-down version (2 MB), as the original with it's 8000 - something Pixels had a whooping 90MB (PNG) and still 34MB as a JPEG.

Sonntag, 21. April 2013

Gimp: How to make Sun Rays

Since I am currently using Gimp a lot, I thought I'd share a tutorial or two, that might come in handy.

This one's simple and demonstrates how to create a sun-ray effect like this:


Create a new canvas and set it's background to being transparent. Then fill the canvas with the color of your choice (above we picked the color #abc977), then from the Toolbar menu pick Filters - Distorts - Blinds:


The settings for Blinds are as follows:

  • From Orientation select Vertical
  • Leave Background/Transparent unchecked
  • Set Displacement to 60
  • Set Number of segments to 10 or whatever looks best for your canvas size (the higher the number, the more rays you'll have in the end)
Confirm your settings by clicking OK. You image now looks like this:


For the final step, select Filters - Distorts - Polar Coordinates. The image above shows the Polar Coordinates dialog. The settings for that dialog are as follows:
  • Circle depth in percent is set to zero
  • Offset angle is set to zero
  • Map backwards is unchecked
  • Map from top is checked
  • To polar is checked
Confirm by clicking OK and you're done :) ! Now there is a lot more you could do with that sun ray, sich as adding a glow by using the Blend Tool etc.

Sonntag, 14. April 2013

BudgetGnome is now live !

It took me a while but yesterday I finally did it :) ! I uploaded my budget management app to the Google Play store, you can check it out here.

The app is easy to use and yet helpful when it comes to keeping track of your monthly expenses and incomes.

The app has been translated to English, German and French.

I plan on adding new features by and by and I'd be happy if you'd give it a try and maybe even give me some feedback on what you think about it.

Here are some first impressions from the app...




Montag, 11. März 2013

ActionbarSherlock:Tabbed Navigation Part 1

I've stumbled over ActionBarSherlock a couple of times now, but did not see the need to actually try it out, until recently a friend suggested that I give it a try, since we wanted to introduce an ActionBar into our application (which runs on Android 2.3.x devices and above).

I'll handle a creating a simple ActionBar with ActionBarSherlock (I'll call it ABS in the future) in another post, since this one is going to be about using the ActionBar for tabbed Navigation.

Here is an example of what navigation tabs look like (taken from the developer pages of android):


To keep it simple this tutorial will cover a tabbed Navigation bar with only two tabs and requires you to have set up ABS already and included it in your project (as a required android library).

The AndroidManifest.xml (without the activity definitions) looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.zainodis.balancemanager"
    android:versionCode="100006"
    android:versionName="1.0.6" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="10" />

    <application
        android:name=".core.Application"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock" >

    </application>
</manifest>


Of course the minSdkVersion and the targetSdkVersion can be different for you,  however it is imperative, that you compile your code at least Android against API Level 14 (as required by ABS).

It is vital, that the theme given in the application is or at least derives from one of the ABS themes. You may hence also create your own theme, as long as you derive it from the ABS themes.

The first step is to create the Activity, that'll create the tabbed navigation bar:

public class TabHostActivity extends SherlockFragmentActivity {

   private static final String SELETED_TAB_INDEX = "tabIndex";

   public static final String TAB_ONE_TAG = "One"
   public static final String TAB_TWO_TAG = "Two"

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     // Setup the action bar
     ActionBar actionBar = getSupportActionBar();

     // Show the navigation bar
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

     // Add the products tab
     Tab budgetTab = actionBar
          .newTab()
          .setText("Tab One")
          .setTabListener(
               new MyTabsListener<FragmentOne>(this, TAB_ONE_TAG,
                    FragmentOne.class));
     actionBar.addTab(budgetTab);

     // Add the about tab
     Tab settingsTab = actionBar.newTab()

          .setText(getString("Tab Two")
          .setTabListener(new MyTabsListener<FragmentTwo>(this, 

                TAB_TWO_TAG, FragmentTwo.class));
     actionBar.addTab(settingsTab);

     if (savedInstanceState != null) {
        int index = savedInstanceState.getInt(SELETED_TAB_INDEX);
        actionBar.setSelectedNavigationItem(index);
     }
   }

   @Override
   protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     outState.putInt(SELETED_TAB_INDEX,

    getSupportActionBar().getSelectedTab().getPosition());
   }
 }


So basically this class'es only responsibility is to create two tabs and make sure, that upon screen rotation the currently selected tab is preserved. If the savedInstance != null check is omitted, you're most likely gonna get overlapping fragments, if you try the following:
  •     Select Tab two
  •     Rotate the screen
Upon rotation, the first tab instead of the second tab will be selected, but the content of the second tab will still be visible and will overlap with the first tab's content.

To avoid this, we make sure to save the index of the  currently selected tab in onSaveInstanceState. In onCreate we create our tabbed navigation as usual, but afterwards we check, if an instance has been saved previously. If this is the case, then we restore the selection.

The Tags (TAB_ONE_TAG and TAB_TWO_TAG) are passed on to the created tags and fulfill a special role: Whenever the fragment within a tab is replaced we need to make sure, to keep using the Tag that was given to the original fragment of this tab. This way we can swap out and find Fragments based on their Tag names. Hence all fragments that'll ever be plugged into the first tab, will always have the Tag TAB_ONE_TAG. The same goes for the second tab, except that here the used tag is TAB_TWO_TAG.

The FragmentOne and FragmentTwo refer to two SherlockFragments, which we'll cover next time, together with the ActionBar.TabListener already referenced in the above code as "MyTabsListener".

Donnerstag, 31. Januar 2013

Blackberry is back!

First: I never had a Blackberry, as the UI was less than appealing but somehow I always liked them and wanted them to improve, so they can keep up with the competition (Windows Phone, Android, iOs etc). Today I stumbled upon a German news article on heise.de and was more than happy to see that apparently they've made a great leap under their new leader Throsten Heins (a German). So far I have mostly been concentrating on Android development, but I'll be more than happy to give Blackberry's (they've changed their company's name from RIM to Blackberry) new operating system a shot.

If you want to get started on developing Blackberry apps, or porting your Android apps to Blackberry, check out their developer website.

The Blackberry Z10 comes with a touch screen, no hardware buttons at all, except for a volume control and features a micro HDMI slot (as well as a micro USB slot)!