Ruler A Programmer's Tool Version 1.3.5 July 29, 1994 © 1994, Digital Objectives All Rights Reserved John Dunning Digital Objectives 1661 Route 22 West Bound Brook, NJ 08805 Internet: jdunning@phoenix.princeton.edu DISTRIBUTION This application is distributed as MailWare: if you use it and like it, drop me a note (email or snail mail). If you don't like it, tell me why and how I can make it better. You may freely use and distribute copies of this software as long as you don't alter it or this documentation in any way and don't charge for its use (the MacHack '94 CD excepted). DISCLAIMER This software comes completely without any warranty. Use it at your own risk. If bad things happen to you or your Newton as a result of using this software, I'll feel sorry, but that's the extent of my liability. INSTALLATION Install ruler as you would any other Newton application. It requires 46,060 bytes. The first time its run, ruler will create a preferences entry in the System soup, if there isn't one already. The entry has the tag "Ruler:DigObj", in case you ever want to remove it. NOTE This utility is intended primarily for developers using NTK or BookMaker. If you're not a developer, you probably won't find it of much use. OVERVIEW If you've used the Newton ToolKit for any amount of time, you'll quickly find that the layout display in the current version has a number of bugs. Views which are not justified from their parent's left and top edges will not appear in the correct position when displayed in NTK, although they'll be fine on the Newton. Positioning these views where you want them generally requires that you fiddle with them in NTK, compile the project, download it to the Newton, check the view's position, and so on through the cycle, until you get it right. That process isn't unbearable, but what makes it even harder is that there's been no easy way to determine a view's position on the Newton. If two views don't quite line up, you've got to squint and try to count the pixels to figure out how far they should be moved in NTK. Recently a screen-capture capability has been added to NTK, so you could also capture the Newton screen, paste it into a graphics application like Photoshop and count the pixels there. But that's also cumbersome. Ruler is intended to simply this process. It's a little utility that displays two crosshairs on the Newton screen. Their position, and the distance between them, is displayed on a floating palette. You can position the crosshairs by dragging them with the pen. That's pretty much all it does, but it does it well. MOVING THE CROSSHAIRS Using Ruler is quite simple. Tapping its icon in the Extras Drawer opens a wide, narrow floating palette. From left to right, there's a standard scroller, two outlined X/Y displays, one width/height display, and a group of four buttons. When the palette is open, tapping anywhere on the screen (other than on the palette, of course) will move the active crosshair to the point you tapped. If the active crosshair isn't visible, it'll appear where you tapped. Dragging the pen across the screen will move the crosshair continuously. You cannot move it outside the visible bounds of the screen (except under certain conditions described below). The crosshair's current X and Y coordinates are continuously displayed in its readout on the palette. If a position display shows two dashes instead of numbers, that means the crosshair has not been positioned yet. Tap on the screen to position it. Besides tapping and dragging, you can also position the crosshair using the scroller. Tapping on any of the four arrows on the scroller will move the crosshair one pixel in that direction. The crosshair will move continuously if you hold down the pen. By tapping on the scroller and dragging the pen away from it, you can increase the speed at which the crosshair moves. The farther you move the pen from the scoller, the faster the crosshair will move. The crosshair is XOR'd against the screen, which means that it will appear white where it crosses a black pixel on the screen, and black where it crosses a white pixel. You can have two crosshairs on the screen at once. Each has a position display on the palette. There can be only one active crosshair on the screen at a time. The active crosshair is drawn in solid black lines, and its display is outlined in black. The inactive crosshair is drawn in grey, with a grey-outlined display. Tapping on the screen or using the scroller will always move the active crosshair; the inactive one will stay where it is. To make an inactive crosshair active, tap on its display on the palette. The display will highlight, its outline will turn black, and the crosshair will also turn black. The currently active crosshair will turn grey and become inactive. If you tap on the active display, it will become inactive, so that both crosshairs are inactive. When this happens, the crosshairs behave a little differently. Tapping on the scroller will move the crosshairs together, so they'll maintain their relative positions. If you tap on the screen, the top left corner of the box formed by the crosshairs will move to the point you tapped. Dragging will move the crosshairs as a unit. If you drag the crosshairs off the screen, their coordinates will be clipped to the visible bounds of the screen. But as long as you don't lift the pen, you can drag them back. If you do lift the pen, the crosshairs will move so that they're visible on the screen, changing their relative positions. Note that if you align the crosshairs horizontally or vertically and inactivate them both, the aligned horizontal or vertical portions of the crosshairs will disappear. If you don't want this to happen, offset the crosshairs by one pixel, or activate one of them. WIDTH/HEIGHT DISPLAY When both crosshairs are visible, the width and height of the square they form, in pixels, is displayed on the third readout, the one with no border. There is a second mode for this readout. Tapping on the button with a diamond on it will display a popup menu. Two of the options on the menu are "Measure pixels" and "Measure offset." Selecting "Measure offset" will change the W/H display to an X/Y display. This mode is discussed in more detail below. BUTTONS There is a group of four buttons on the right end of the palette. The bottom right button is the standard close box. Tapping it quits Ruler. The top right button (a tiny square) toggles between the full-size palette and an iconified mode. In the iconified mode, the crosshairs are hidden and the palette shrinks to a tiny square, which can be repositioned by dragging on its grey border. Tapping on the single button in the iconified palette will return it to its full size and to its position before it was iconified. After you open Ruler, you'll usually want to shrink the palette. If you don't, you won't be able to open the application you want to measure because the crosshair layer covers the entire screen. Once the application is open, expand the palette to its full size and start measuring. The top left button (a vertical or horizontal line) toggles the palette between a vertical and horizontal orientation. When you change its orientation, the palette will move so it doesn't hang off the edge of the screen after it has rotated. The bottom left button (a diamond) pops up a menu of the following options: About Ruler: displays an about box for Ruler. Print local box: prints a viewBounds frame to the Inspector, if it's connected. Since this is a local box, the left and top values will be 0, and the right and bottom ones will be the width and height of the box formed by the crosshairs. Print global box: prints a viewBounds frame to the Inspector, if it's connected. The frame will contain the global bounds of the box formed by the crosshairs. Print view origin: prints a frame containing left and top coordinates to the Inspector, if it's connected. To calculate these points, Ruler assumes the second crosshair is positioned on the view's origin and the first is positioned on the origin of the view's parent (or sibling, if it's sibling justified). This function is discussed in more detail below. Measure pixels: Measure offset: these two options determine what information the third (unoutlined) display shows. In the default position, the display will show the width and height, in pixels, of the box formed by the two crosshairs. If only one crosshair has been set, two dashes will be shown instead. Selecting "Measure offset" will cause the display to show the offset from the first crosshair to the second, in x,y coordinates. In this mode you will also be able to drag the crosshairs off the right and bottom edges of the screen (coordinates 240 and 320 or 336, respectively). The only other difference in these two settings is that the pixel values will always be positive and will be one greater than the offset values. It's necessary to have these two options to handle the case where, for instance, the x coordinate of the first crosshair is 4 and the x coordinate of the second is 2. In this example, the crosshairs span 3 pixels, but the offset is -2. Open iconified: selecting this option will cause Ruler to always open in the collapsed, iconified mode. You will probably want to leave this item checked, because the application you want to measure will likely be covered by the Extras Drawer after you open Ruler. To close the Extras Drawer, you'll have to iconify Ruler, so this option saves you a step. POSITIONING THE PALETTE To move the palette around the screen, you can drag it by its grey border. Another good way to drag the palette is to put the pen on the width/height display, which is easier to hit than the border. When the palette is iconified, you can also drag it by its grey border. Ruler remembers the positions of the full-sized palette and the iconified palette separately. This is useful if you want the iconified palette to always move to the bottom right corner of the screen, for instance. While you are dragging the palette, the crosshairs will disappear. They will reappear when you stop dragging. This is normal. If your Newton goes to sleep while Ruler is open, it will be iconified the next time you turn the Newton on. It's necessary to do this to keep the screen from turning white when you switch the Newton back on. USES FOR RULER One of the simplest ways to use Ruler is to make sure that two or more views are aligned horizontally or vertically. With one crosshair, you can just eyeball the alignment. With two, you can use the "Measure offset" option to show how much the view bounds need to be changed to bring the views into alignment. With the "Measure pixels" option, it's a snap to measure the width and height of a bitmap, assuming there's no extra white space around it, which obviously won't show up on a white background. There are some subtleties to measuring views which you should be aware of. If you want to measure the width and height of a view, you must position the crosshairs just *inside* the view's border, because borders are drawn outside a view's bounds. Remember also that a border can have an inset value. If the inset is white, it may look like the border is narrower than it really is. The matte border style, for instance, has a 1-pixel white inset, so its full width is 6 pixels, even though only 5 are taken up by the grey and black lines. To measure a protoFloater view then, you should leave one pixel of white space between the crosshairs and the inner grey border. You can make sure several views are the same size or are evenly spaced by deactivating both crosshairs. Position them so that the box they form is the size you want. Then tap the active crosshair's display, so that both displays are outlined in grey, not black. You can now drag the crosshairs as a unit and position them anywhere on the screen to check that other views are the same size or separated by the same amount. It's possible to measure the offset of a view from its parent, assuming both it and its parents borders are visible. However, the view's justification values can complicate this procedure. The best way to see this is to load the ViewTest package, which should have been included with Ruler. (Note that this package was created on a MP0, so it might be messed up a little on a MP110.) First open Ruler, iconify it, open ViewTest, then expand Ruler and check the "Measure offset" option. ViewTest simply displays a few views with single pixel borders. Each view shows its bounds and its justification values (P = parent, S = sibling, L = left, R = right, T = top, B = bottom). The top view is justified from its parent's top and left edges, and its parent's origin is at (0,0). To find its top and left bounds, position the first crosshair at the view's parent's origin (the top, left corner of the screen) and position the second crosshair at the view's origin, just inside the border. The third display, now labeled X/Y, will show the view's origin, (47,42). Not a terribly interesting example. The second view is more exciting. It's also parent-justified left and top, but it's sibilng-justified left and bottom. Its sibling is the first view, so you need to position the first crosshair on that view's bottom, left corner (which is its origin, as far as the sibling view is concerned). However, because of the way view bounds relate to screen pixels, you must put the first crosshair *on* the view's bottom border, not inside of it, although it should still be inside the left border. Then put the second crosshair on the sibling view's origin. The X/Y display should show (10,20). This special case also applies to the right edge. So whenever a view is justified to its parent's or sibling's bottom and/or right edge, you must position the first crosshair directly on the parent's or sibling's bottom and/or right edge. You can see this with the bottommost view in ViewTest. It is parent-justified right and bottom. It's parent is the app's base view, and the app view fills the entire screen. Since its border is off-screen, you must set the first crosshair just off-screen, at (240,336 or 320). This is why you can drag the crosshairs off the bottom and right edges of the screen in "Measure offset" mode. Play around with ViewTest until you are comfortable with determining the top and left bounds of a view. CAVEATS It is possible to measure floating views with Ruler, but since the view floats, it is above the crosshair layer. The crosshairs will be drawn over the floating view, but the view will be "live," i.e., you can't tap on it to position a crosshair. You can, however, tap somewhere else on the screen and drag the crosshair over the floating view. Once you stop dragging, you'll need to use the scroller to position the crosshair further. Closing a floating view while Ruler is expanded will leave a white square where the view used to be. To restore the screen, iconify and expand the palette. You can do this whenever there's garbage on the screen that doesn't seem to go away. Be careful of where you tap to dismiss the popup menu on systems earlier than 1.3. Since the crosshair layer is hidden while the popup menu is open, whatever is underneath will receive the tap. If things get really messed up, it is possible for the Ruler palette to be closed while the crosshair layer is still open. Tapping on the screen should throw an exception, which should cause the crosshair layer to close itself. If things get really, really messed up, the crosshair layer might be closed but the screen might not update, so that it looks like nothing happened but you can hear the Extras Drawer open and close, etc. In this case, you have to reset the Newton.