New UI for MotioninJoy

2013

If you use MotioninJoy to connect Playstation 3 controllers to your computer as gamepads, then you are probably well aware that the configuration utility is far from pretty or user-friendly. I just finished rewriting the UI to not suck. Check it out at the link below, then come back here to tell me all the things I broke so I can fix them.

MotioninJoy UIRewritten, offline UI for the Playstation 3 gamepad tool, MotioninJoy

GlassCalc 2 Update

2011

As great as Mathieu Jacques’s MTParser is, it only supports double-precision floating point numbers and it only works with .NET through a COM interface, which means I have less control over the parser and I have to register the dll.  Therefore, GlassCalc 2 will feature a new parser which I am writing from the ground up. I call this new parser GCParser. I am awesome at naming things.

Here is a fairly technical description of how GCParser will work:

Design Goals of GCParser

  • The parser will operate on objects deriving from GCObject. This is a completely generic class, and in fact, the only function a GCObject must have converts the object to a string so it can be displayed.
  • GCParser will have two types of GCObject out-of-the-metaphorical-box: numbers and arrays. Arrays are lists of GCObjects. This means GCParser will support vector operations, and since you can make arrays of arrays, probably matrix operations too.
  • The syntax for arrays should be familiar to anyone who has programmed in C or JavaScript. a = [1, 2, 3] is a 3-element array. a[0] retrieves the first element of the array.
  • GCObjects can have properties and functions. For instance, arrays will have x, y, and z properties to make 3d vector operations easy. [1, 2, 3].x will return 1. Also, [2, 3, 1].sort() would return [1, 2, 3].
  • GCParser will be able to operate on multiple types at once. For instance, when executing 2 * [3, 4] the parser would search for a Multiply function taking two arguments of types GCNumber and GCArray. This expression would evaluate to [6, 8]. If no function was found, the parser would throw a type error.
  • GCParser will be extensible. Extensions will be able to define not only constants and functions, but new GCObject types as well. For instance, a complex numbers extension could define a GCComplexNumber class, functions for operating on complex numbers, and a constant i. Since the parser will only create numbers and arrays normally, the extension would also need to define a constructor function, Complex(real, imag), to make complex numbers. If the extension defined functions for adding/multiplying numbers and complex numbers together, the expression 1 + 2i would also work. The parser would interpret this as (number: 1) + ((number: 2) * (complex: 0 + i)).
  • I haven’t figured out how this would work yet, but I want GCParser to support expressions like [1, 2, 3].sort((a,b) => b<a). This would send a predicate function to the sort function telling it how to sort—in this case, sort descending. Likewise, Sum(n => 0.5^n, 1, 50) would sum 0.5n from n = 1 to 50.
  • Parsing occurs in three stages: tokenization, parsing and evaluation. Tokenization takes the expression and figures out what all the individual parts mean. It also generates a structure which the syntax highlighter can use instead of the convoluted regular expression system GlassCalc currently uses. Parsing takes the tokenized expression and converts it into a binary tree of operations. Evaluation traverses the tree, running each operation until it gets a final result. Parsing and evaluation will not run on the UI thread, so the program won’t freeze up if you run a long calculation.

Things That Are Not Design Goals of GCParser

  • Be really fast.

tl;dr Version

  • GlassCalc 2 will have a new parser. It will be magic, rainbows and unicorns. It will calculate just about anything.
  • If it can’t calculate something, you can probably write an extension so it can.

So, when will it be done? Eventually. I have the tokenizer mostly complete. I am waiting for .NET 4.5 to be released before I start work on the UI, as I will make use of its new asynchronous stuff.

GlassCalc 1.35

2011

It has been far too long since I last updated GlassCalc. There’s a new version with some bug fixes. Check the GlassCalc page for download links.

This update fixes some bugs caused by GlassCalc applying exponential formatting to hexadecimal numbers containing “e”. It also fixes a formatting bug where a thousands separator would appear next to a negative sign (ex: -100 was displayed as - 100) and a syntax highlighting bug where a variable ending with the name of a constant would be highlighted partially as a variable and partially as a constant.

Also, here’s a status update on GlassCalc 2: I’ve decided that MTParser isn’t capable of all the things I would like to do with GlassCalc, and none of the free parser libraries I’ve encountered are either, so I am now writing my own parser (MTParser is excellent, but its existence as a COM component makes installing GlassCalc a pain and it doesn’t support lists or higher precision math). The primary goals of the new parser are:

  • Support all of the GlassCalc’s current syntax without tons of regex magic.
  • Allow for basing syntax highlighting off of the parsed expression instead of using even more regex magic.
  • Add support for lists (what you math people might call n-dimensional vectors) and possibly lists of lists (which could be used to perform matrix math).
  • Possibly add support for high-precision math.

So far, I have a system that tokenizes an expression character-by-character as you type it—that is, it splits the expression up into numbers, operators, symbols, and so on. The cool thing about doing this character-by-character is that by the time you hit Enter to evaluate, part of the parsing work is already done. In fact, I can use this already-finished part to speed up syntax highlighting and to show you the result of simple calculations before you even hit enter without reparsing every time you add a character. Of course, if you start messing with the middle of your expression, I have to reparse everything.

I am also experimenting with different GUI designs. I may post some mock-ups here later to see what you think.

Also, once I have made a little more progress, I’m going to put GlassCalc 2 up on Github. That’s right, GlassCalc 2 is going to be open source. The only thing keeping me from open-sourcing GlassCalc was figuring out what MTParser’s license would and wouldn’t let me do with regards to distributing MTParser’s source/binaries. Now that I’m not using MTParser, there aren’t any problems with going open source.

Plans for GlassCalc 2

2011

When I first started writing GlassCalc, I never imagined how many cool new features I would come up with later. With the way some parts of GlassCalc are written, it’s becoming harder and harder for me to add in some of the things I want to add, so I’ve decided that the next major version of GlassCalc will be a rewrite of much of the code.

I’ve just started planning GlassCalc 2, and there are a few other projects I want to finish up before I even start writing code for it, (in other words, don’t expect it any time soon) but here are some of the features I have planned:

UI Changes

  • Notify of updates with native Win 7 notifications if available. Clicking on notification bubble will open regular update window.
  • Replace separate constants,variables, functions views with a single block containing all three items. Maybe use an accordion style control like Opera 11′s mail panel. This should save some vertical space and not look ugly when it is taller than the window.
  • Replace function references block with a dedicated function reference window. Access it from the help menu. This window could also show the info that is currently in quickref.txt. Functions will be sortable alphabetically, by type, (trig, probability, etc.) or by the extension that added them.
  • When hovering over a variable or custom function, show an “x” button to delete it.
  • Remove “Input” text from input box. Put an “=” button to the right. Text/icon inside this button changes depending on context:
    • If no text input, show “=”
    • If auto-evaluate is on and input is simple, show result of expression. Button should smoothly expand to fit text.
    • If auto-evaluate is on and input is complex (commands, multiple expressions) show “=”
    • If another expression is still being evaluated, show spinner icon
  • Add button to header of the history view that toggles between the view’s regular styling and plain text. This will allow selecting multiple lines at once.
  • Redesign settings window. Most likely, place categories in list on the left like in Visual Studio. Keep window the same size no matter which category is selected.
  • Maybe add a code-completion tooltip that would show all constants, variables or functions starting with what you’ve typed. Could activate automatically or on Ctrl+Space.
  • Add option to display bases as a subscript, like 1001102

Internal Changes

  • Separate parser/evaluator from the UI thread so that GlassCalc will not freeze while performing long calculations.
  • Add an “auto-evaluate” mode which evaluates expressions and displays the results as you type.  Result of auto-evaluation will most likely appear to the right of the input box, though a dimmed result in the history view might work too.
  • Replace slow, unfindable xml config files with an ini settings file at %AppData%\GlassCalc.
  • Add extensions system. Extensions will be able to extend the default constants and functions and add scale factors. The user will be able to turn them on and off individually. Extensions will most likely consist of a single ini file with the extension’s name, author, and all the other info. If an extension requires a complex function that cannot be represented in a single GlassCalc expression, .cs scripts can be linked in. An xml file containing documentation can also be included.

GlassCalc 1.29 and Widgets!

2010

GlassCalc 1.29 doesn’t add any new functions, but it adds a number of formatting features to make GlassCalc easier to work with or just fit into your theme better.  GlassCalc now has support for thousands separators, and you can choose between commas, spaces of various widths, or enter your own separator.  GlassCalc can also replace asterisks (multiplication operators) with dots or times symbols.

You can now choose between three different formats for exponential form: 1.00e10, 1.00E10, and 1.00×1010.  GlassCalc defaults to a lowercase e to give a clear separation between the number and exponent.  More color settings are available, and the font sizes of the history, input, and other panes are now configurable as well.

Widgets!

I recently created two Opera Widgets, which are essentially desktop applications built with HTML, CSS, and JavaScript.  You need to install Opera before they will work, though Opera does not need to be running to start the applications.

Search Organizer

If you are an Opera user and wished you could reorder your custom search engines, check out my Search Organizer widget.  Feed it your search.ini file and it lets you drag and drop your search engines into a new order.  Save and restart Opera for your changes to apply.

CSS Fix

My second widget isn’t exclusively for Opera users, though it may be more useful to them.  Occasionally, I’ll run into a site that looks blocky and ugly in Opera, but smooth and pretty in Firefox and Chrome, even though Opera supports most or all of the features used *cough* Twitter *cough*.  There’s no reason these sites should look any worse in one browser compared to the others, except that the web developers left out some key CSS properties, like the unprefixed border-radius and box-shadow.

CSS Fix aims to solve this problem by generating CSS patches to fix sites.  It knows most of the equivalent CSS properties used by Opera, Firefox, Chrome/Safari, and Konqueror and can translate between them.   Simply enter the URLs of a offending sites and/or CSS files, choose the browser(s) you want a patch for, and CSS Fix will download the files and generate a new stylesheet with all the missing CSS properties.  You can export the patch as user CSS or user JavaScript, install the patch in your browser, and see sites the way they were meant to be seen.  (You could also ask the site admins to kindly add in the missing properties, but for big sites like Twitter, you’d be lucky to get anywhere)

I’ve created a Twitter patch for Opera using CSS Fix that gives Twitter the rounded corners and most of the other pretty effects it’s supposed to have.

I am also working on a web-based version of CSS Fix that lets you paste in CSS and a user JavaScript version which will fix inline styles on the fly.  I can’t estimate when either of those will be done though.

Aero Glass in GlassCalc (part 1)

2010

I got a couple questions about how I made the Aero Glass effects in GlassCalc. When I started making GlassCalc, I had no idea how to manage Aero Glass, but Google came to my rescue. What I eventually came up with is the amalgamation of code snippets and general knowledge from countless separate articles and examples. I’ll link to as many of those pages as I can remember, but I’ll try and bring everything together in one place here.

Note: GlassCalc is written in C# using WPF for its UI. As such, some of the code examples below are C#, .NET, or WPF specific.

Every window in Windows has a client area and a non-client area. The client area is everything you get to handle and draw on. Normally, this is everything inside the window frame. The non-client area is everything Windows handles by itself: the window frame, icon, window title, min/max/close buttons, resize handles, etc…

Using the Windows API, programs can modify the glass frame and the client/non-client areas. Generally, they either extend the glass frame into the client area, or they extend the client area into the glass frame. GlassCalc does both.

With the default interface, GlassCalc extends the top and bottom of the frame. The client area is still the same size, but the glass frame has been extended into the client area, so GlassCalc can draw the menu and the input box over glass.

[singlepic id=6 w=320 h=240 float=center]

With the full glass interface, GlassCalc extends the frame to cover the entire window, so everything is drawn over glass, but it also draws the menu bar inside the title. This is done by extending the client area upwards so GlassCalc can draw there. This effect takes quite a lot more work, because now that GlassCalc has taken over the non-client area, it must handle all the things Windows used to handle in this area.

[singlepic id=13 w=320 h=240 float=center]

Extending the glass frame

All of the code here involves Windows API calls in some way. To organize everything, I’m putting all Windows API functions and structures in a class called Interop. (some examples use the name NativeMethods) I’ll also make a class called GlassHelper which will (quite appropriately) help deal with Aero Glass.

To extend the glass frame, we need to import a function called DwmExtendFrameIntoClientArea from dwmapi.dll. Since Aero can be disabled, we also need to know whether we can extend the frame or not. For this, we import DwmIsCompositionEnabled. DwmExtendFrameIntoClientArea takes a Margins structure as one of its arguments. Since there is no Margins structure in C#, we need to define it ourselves. Much of the following code comes from this informative article.

Note: You can copy the source of these code examples by hovering over the code, then clicking the view source icon in the toolbar that appears in the upper-right corner.

public static class Interop
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Margins
    {
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;
        public Margins(Thickness t)
        {
            Left = (int)t.Left;
            Right = (int)t.Right;
            Top = (int)t.Top;
            Bottom = (int)t.Bottom;
        }
    }
    [DllImport("dwmapi.dll", PreserveSig = false)]
    public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref Margins margins);
    [DllImport("dwmapi.dll", PreserveSig = false)]
    public static extern bool DwmIsCompositionEnabled();
}

Now, we’ll make a class that can make use of these functions.

public static class GlassHelper
{
    /// <summary>
    /// Gets whether dwmapi.dll is present and DWM functions can be used
    /// </summary>
    public static bool IsDwmCompositionAvailable
    {
        get
        {
            // Vista is version 6.  Don't do aero stuff if not >= Vista because dwmapi.dll won't exist
            return Environment.OSVersion.Version.Major >= 6;
        }
    }
    /// <summary>
    /// Gets whether DWM is enabled
    /// </summary>
    public static bool IsDwmCompositionEnabled
    {
        get
        {
            // Make sure dwmapi.dll is present.  If not, calling DwmIsCompositionEnabled will throw an exception
            if (!IsDwmCompositionAvailable)
                return false;
            return Interop.DwmIsCompositionEnabled();
        }
    }
    /// <summary>
    /// Extends the glass frame of a window
    /// </summary>
    public static bool ExtendGlassFrame(Window window, Thickness margin)
    {
        if (!IsDwmCompositionEnabled)
            return false;
        IntPtr hwnd = new WindowInteropHelper(window).Handle;
        if (hwnd == IntPtr.Zero)
            throw new InvalidOperationException("The Window must be shown before extending glass.");
        HwndSource source = HwndSource.FromHwnd(hwnd);
        // Set the background to transparent from both the WPF and Win32 perspectives
        window.Background = Brushes.Transparent;
        source.CompositionTarget.BackgroundColor = Colors.Transparent;
        Interop.Margins margins = new Interop.Margins(margin);
        Interop.DwmExtendFrameIntoClientArea(hwnd, ref margins);
        return true;
    }
}

Finally, in override your application’s OnSourceInitialized method to call ExtendGlassFrame. The Thickness object you pass in defines how far in the frame should be extended from each of the sides. If you use -1 for each dimension (like in the code below), the glass will cover the entire window.

public sealed partial class YourApp : Window<
{
    . . .
    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
    }
    . . .
}

Make the glass area act like an extension of the title bar

If you extend the frame from the top such that the title bar appears bigger, (like in the default GlassCalc interface) you probably also want to make it so that when a user clicks in this empty area, they can drag the window. You can do this by detecting a MouseLeftButtonDown event inside the extended title bar area and calling your window’s DragMove function.

What if Aero gets disabled while my program is running?

There is one other thing you should take care of when extending the frame. If a user turns off Aero while your application is running, you’ll get big black areas where there used to be glass because your window background is transparent. Windows sends a WM_DWMCOMPOSITIONCHANGED message to your application when Aero is turned on or off, so you can handle this by setting up a function to listen for this message.

Add this constant to Interop.

public static class Interop
{
    public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
    . . .
}

Now, set up a function to listen for messages. When it gets a WM_DWMCOMPOSITIONCHANGED message, check to see whether Aero was enabled or disabled. If Aero was enabled, extend the frame again. If it was disabled, set the background color back to its original value. (This example assumes your window background was white. You could improve it by saving the background color before extending the frame, then reverting it when Aero is disabled.)

public sealed partial class YourApp : Window
{
    . . .
    /// <summary>
    /// Processes messages sent to this window
    /// </summary>
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == Interop.WM_DWMCOMPOSITIONCHANGED)
        {
            if (GlassHelper.IsDwmCompositionEnabled)
            {
                // Aero was re-enabled.  Extend the glass again.
                GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
            }
            else
            {
                // Aero was disabled.  Reset the window's background color to remove black areas
                HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
                source.CompositionTarget.BackgroundColor = Colors.White;
                this.Background = Brushes.White;
            }
        }
    }
    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        // Hook up the WndProc function so it receives messages
        HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
        source.AddHook(WndProc);
        GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
    }
    . . .
}

Extending the client area

Since this is already a very long post, and the part on extending the client area will probably be even longer, I’m going to split it up. Extending the client area into the frame will come in part 2… whenever I get around to writing that. For now, here are some of the links I found most useful while figuring this stuff out.

Update 8/19/2010: I know it’s been over a month since I posted part 1, and I still haven’t gotten to part 2.  I’m working on it, but school is start back up, so I can’t say when it’ll be done.

Putting Netbeans AppData in the Right Place

2010

If you use Windows Vista/7 and Netbeans, you’ve likely seen a .netbeans and .netbeans-registration folder appear in your user directory. Netbeans is a very nice piece of software, but like many open-source programs, it goes by the mistaken belief that application data always goes in the home folder. This is perfectly normal for Linux, but Windows is not Linux. Windows application settings go in the AppData folder. It is possible to get Netbeans to store its settings in the right place, and it isn’t too difficult.

This guide will show you how to put Netbeans settings in the right place for Windows Vista/7, but you can also use it to put the settings directories anywhere you want on any system. I’ll assume you are using Netbeans 6.9. If not, change the version number where appropriate.

Find netbeans.conf

Open an explorer window and find the directory where Netbeans is installed. The default location is C:\Program Files\Netbeans 6.9 (C:\Program Files (x86)\Netbeans 6.9 for 64 bit systems). Inside it, there should be a folder called etc and inside that, a file called netbeans.conf. Run an instance of your preferred text editor as administrator (you won’t be able to save the file otherwise) and open netbeans.conf in it.

Change netbeans_default_userdir

The second line of netbeans.conf defines the settings directory. Change it to look like this:

# ${HOME} will be replaced by JVM user.home system property
netbeans_default_userdir="${HOME}/AppData/Roaming/Netbeans"

If you move your .netbeans and .netbeans-registration folders to this new location, Netbeans will pick up your settings, but it will still create the same two directories in your user directory and it will ask you to register again. This is because there are actually two options you need to change. The second one is a little harder to find.

Define -J-Duser.home

Line 6 of netbeans.conf defines a bunch of options, each starting with -J. You need to add another option to this line. Before the quote at the end of the line, add this: (replace USERNAME with your username)
[code lang="text" light="true"]-J-Duser.home=C:/Users/USERNAME/AppData/Roaming/Netbeans[/code]

Your netbeans.conf file should look something like this now.

# ${HOME} will be replaced by JVM user.home system property
netbeans_default_userdir="${HOME}/AppData/Roaming/Netbeans"
 
# Options used by NetBeans launcher by default, can be overridden by explicit
# command line switches:
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true -J-Duser.home=C:/Users/USERNAME/AppData/Roaming/Netbeans"
# Note that a default -Xmx is selected for you automatically.
. . .

And now you’re done! Netbeans should no longer clutter your user directory with its settings.

Adsense, Without Blocking

2010

My web pages pause at ads for a moment. Why?

In some (but not necessarily all) web browsers, if you place a script in the middle of a web page, it has to be executed before the browser can continue rendering the page. The AdSense script is quite slim, but your browser still has to request the JavaScript file from Google, which could take a while depending your Internet speed. This means your pages might load up to the ad, pause a little while, then continue loading. Fortunately, there is a very simple way to keep scripts from blocking your content: put them at the end of the page. This way, all your content is loaded before the scripts are downloaded and executed. Unfortunately, this also puts all your ads at the bottom of the page, but with a little JavaScript, you can put your ads back where they belong.

How to fix it

First, you’ll need some sort of placeholder for where an ad should go. Use a div and set its id so you can easily find it with JavaScript. If you have multiple ads, number the ids so you can replace them all with a loop.

<div id="ad-0"> <!-- the first ad goes here --> </div>
<div id="ad-1"> <!-- a second ad goes here --> </div>

Now, place the AdSense JavaScript at the end of the page. Put each ad inside a div with an id so you can easily find it with JavaScript. Put the everything in a div with display set to none so your ads won’t briefly appear at the bottom of the page.

<div style="display:none">
  <div id="adsource-0">
    <script type="text/javascript"><!--
    google_ad_client = "pub-xxxxxxxxxxxxxxxx";
    /* Ad Name */
    google_ad_slot = "##########";
    google_ad_width = 125;
    google_ad_height = 125;
    //-->
    </script>
    <script type="text/javascript"
    src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
    </script>
  </div>
  <div id="adsource-1">
    ...
  </div>
</div>

Finally, use JavaScript to move each ad to its proper place. This script uses document.getElementById to find the ad and the placeholder, then it uses appendChild to move the ad into the placeholder div.

<script type="text/javascript">
numAds = 1;
for (var i = 0; i < numAds; i++) {
    source = document.getElementById("adsource-" + i);
    placeholder = document.getElementById("ad-" + i);
    placeholder.appendChild(source);
}
</script>

How well does it work?

Consider this entire site a live tech demo. Refresh the page and watch under the “Advertisements” header of the sidebar. After all of the content is loaded, the ads pop into place.

It breaks my layout!

With this setup, the placeholders initially take up no space, so they expand when the ad gets loaded. If this breaks your layout, you can set the height and width of the placeholder to the dimensions of the ad like this:

<div id="ad-0" style="width: 125px; height: 125px"> <!-- this placeholder takes up space! --> </div>

Edit (A bit later, still June 4)

Apparently, this is what I get for writing a post about AdSense. See? This is why we can’t have nice things.