// From http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits
unsigned char b; // reverse this byte
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;

March 7, 2010

Resistor Roid: Prettier, More Productive

Filed under: Uncategorized — jon @ 1:52 am

Just a few changes I want to mention:

  • Buttons are now based on the default android button, and use setColorFilter(color, Mode.MULTIPLY) to achieve the coloured button effect.
  • I realised I wanted to know the digit while I was entering the colour, and this lead me to thinking that there was no real reason to separate the colour-to-numeric and numeric-to-colour lookups.
  • I bothered to lookup the unicode for the ohm symbol (2126).
  • It has a name: “Resistor Roid” and a logo (based on the official android logo):

The first two bands are simple – just enter the digit regardless of the unit and regardless of whether it’s 32, 320 or 3.2. The third band (the multiplier) is the clever bit. Instead of trying to present a multiplier directly, it shows the end value you actually want. So if you want 3.2kOhm you enter “3″ then “2″ then touch the button which has “3.2kOhm” on it which I think is much more straight forward than “x10^2″ or “x100″.

This is the point where I can really see the application taking shape; and start to assess its value. The UI seems as intuitive in practice as I’d hoped in theory (no substitute for user testing of course) so I’m happy that it’s worth continuing.

My immediate plan to get it ready for the first market release is:

  • Replace that hideous resistor image
  • Use a different drawable to distinguish the gold/silver buttons from yellow/grey. I could probably make some of the other colours clearer too
  • See what IEC 60062 has to say. I can see ambiguities if black is allowed in the first band, but most calculators allow it.
  • Tidy up the internal calculations. There are some things being calculated too often. Ok, so it’s unlikely to be a bottleneck, but this is a mobile app, plus it’s always nice to work with clean code.
  • Implement slide-back, slide-forward to move between the bands.
  • Force portrait mode

After that, these will be top of the list:

  • Add a menu to switch between just colours, just numeric and both.
  • Add five band mode

March 6, 2010

Resistor App: Build 0001

Filed under: Uncategorized — jon @ 12:50 am

Ok, maybe not quite the very first build, but still. It’s the first version I felt achieved something, and here it is running in the emulator:

resistor-app-1

So the colours are wrong (and there aren’t enough of them) but they are buttons, generated programatically with the setBackgroundColor() called to set the colour of each one; simple. The app actually works – to the point where it tracks the current state, updates the displayed value with each button press, and wraps back round to the first band. Of course you also have to track the current state since it isn’t shown anywhere ;).

Displaying the current state with a resistor image

To address this most immediate flaw, and start inching closer to my original design I need to get an image of a (blank) resistor to display at the top. In itself this is trivial (ImageView), but I know I will need to do much more with this resistor display. I’ll need to overlay the bands, show the current band, and possibly detect touches to change the current band. The cleanest way to do this is with a custom component.

A lot of documentation reading followed, as it’s easy to do things the wrong way if you dive too deep too early into an unknown API. Still, it should be simple to render an image on whatever components paint on, right?

Well it turns out I had a bit more to learn about resources first.

The first step is easy, simply copy resistor.png into res/drawable. A resource id will magically appear in the R class. The onDraw method seems simple enough, and looking at the example custom view from the android docs, the Canvas parameter is pretty much as you’d expect: It’s something to draw on; somewhat analogous to the Graphics parameter passed to the paint() method in Swing. Sure enough it has a drawBitmap() method which expects a Bitmap argument which… doesn’t really get you any closer to loading anything from that resource.

Now I had hoped that the relevant method on Canvas would tell me what type I had to get my image into (did I pass the resource id? Load a Bitmap? Create a Drawable?), but that idea having come to a dead end I resorted to a google / stackoverflow search for the answer. It turns out you need to load the image resource into a Drawable (it will in fact be a BitmapDrawable but we never need to know that), and tell it to paint itself onto the Canvas, which is logical enough once you know you’re going to be dealing with Drawables. This bit of code from my custom view’s onDraw() method does the actual drawing:

Resources res = getResources();
Drawable dr = res.getDrawable(R.drawable.resistor);
dr.setBounds(0,0, getWidth()-1, getHeight()-1);
dr.draw(canvas);
...

A couple of things with noting:

  • We have to set the bounds of the drawable before asking it to draw itself on the canvas. I think this is a bit clumbsy personally, and don’t really like the asymmetry compared to say canvas.drawRect(l,t,r,b,f)
  • If we want to fill the area allocated to this View, we have to get the width and height from the View not from the Canvas

So the above code, a bit more code to call drawRect() to draw the bands and selection border and the world’s worst drawing of a resistor later…

The eagle-eyed may notice I also corrected the colours.

Staggeringly this is all it took to create a useful, usable android app. Now there’s no way this is distributable let alone worth selling, but it’s a reasonable base to evolve from.

Next up: Those ugly buttons

:wq

Next Page »