By Daniel Wood, 9 January 2011
Using Popup windows is common FileMaker technique for showing more information, managing dialogs, and running wizards to name a few. However, all to often little care is given to the aesthetics of creating and positioning a popup, leading to an unpolished and half-finished feel. This article gives some pointers on how you can create popups that are clean, efficient, and correctly positioned.
Why would you want tidy popups?
Consider any standard application on your computer, such as iTunes, Mail, Safari etc. When you open new windows in these applications, such as entering the preferences, what do you see? Typically, you will see the popup windows appear centered in front of your current window. They appear right away, and they appear all setup and ready to go.
Now, if an application can do it, then why shouldn't your database? Databases are just as critical as applications, if not more, so why skimp on the detail?
Having tidy popups makes your entire database feel tidy and polished, and can be achieved very easily.
All too often I see popup windows created in FileMaker with no care. How many popups have you seen in databases that appear in seemingly random positions, with the incorrect size, showing scrollbars or status area. Then, how many do their setup on-screen, so you see the hiding of the status area, the resizing of the popup, layout changes and so on? I don't know about you, but I see it all the time and it is one of my biggest bug-bears about database design - the lack of care taken on the user interface and design side of a system.
If you are building any kind of commercial database, then how it looks and behaves should be one of your top priorities, no one wants to buy a database that looks half-finished !
Setting up a popup without the user seeing
The creation of new popup windows that are not visible to the user has already been covered in one of my previous articles - "Using an Offscreen Window to do a Scripts Work".
The idea is that new windows are created with a large negative left coordinate value, this ensures the new window appears at a coordinate not visible by monitors, and so is not on-screen.
The article above concerns using these windows as temporary workspaces which can be closed when done, but the same idea can apply to creation of popups the user will eventually see. The popups can be created with it's width, height, and top coordinate set correct for the popup, but with the large negative left coordinate. When the popup is ready to be displayed, it can be shifted back on-screen in a single step using the "Move/Resize Window script step.
In the images above, you can see how the new popup window can be created. Local variables have been used to store the default top/left coordinates, and the popups default width and height.
Positioning the popup where you want
Depending on the purpose of the popup window you are creating, there may be many different initial locations on screen where you want the popup to appear. If you know the actual coordinates, such as wanting the popup to always appear in the top left corner of screen, you can obviously enter 0/0 as your coordinates.
However, more often than not the position of a new popup will be dependent upon the location of your current window. For example, if you wish to have the popup appear directly centered in front of your current window, then the initial coordinates of the popup are dependent upon the current coordinates of your main window.
Similarly, you may wish to position the popup in a location relative to an object on your layout. Small popup windows may be used to carry out an action specific to a location such as a particular button, or field. In this case, your popups initial coordinates are dependent upon the coordinates of the layout object.
Center-Aligning a popup window
To create a center-aligned popup window, I have created a couple of helpful custom functions that perform the necessary calculations to derive a top and left coordinate for your new window:
The popup_CenterLeft function takes your popups initial width as its parameter. This is required to position the popup correctly horizontally. Similarly, popup_CenterTop requires the popup height to center vertically.
I won't go into great detail as far as dissecting the functions, suffice to say they produce the coordinates using the popups dimensions, compared to the current windows dimensions and location on screen.
The image above shows how you can establish your popups coordinates in variables. Here, $Width and $Height have been previously set to the popups initial dimensions.
Establishing the popups initial dimensions
This is the most crucial part of the process in my opinion. In order to prevent visible scrollbars when you popup is displayed, you should set your width and height exactly correct for the popup. This is going to involve determining the exact dimensions. Some may think that this "hard-coding" of dimensions into your script is a bad thing, but I say that if you are creating a popup window, it is highly unlikely its dimensions will change unless you manually make changes to the layout, in which case your script should change accordingly. It is also important to get correct dimensions so you see no window resizing toward the end of the process.
In the image above I have set my width and height into variables. You'll notice the use of two more custom functions popup_GetWidth and popup_GetHeight. These functions help correctly determine your windows dimensions.
The reason for using these functions is because there is a difference in window dimensions depending on whether you are on a PC or a mac. On a PC, scrollbars are thicker and so the window will be larger. These functions take as their parameter the raw layout-mode width/height of your layout, and produce the resulting windows dimensions based upon what platform is being used.
To determine your layout height, you will need to obtain the pixel heights of your layout parts. If your layout has a header of height 50 pixels, and body part of 100 pixels, then your parameter to popup_GetHeight is going to be 150. Of course, if your popup is using list/table view, this becomes less important, and your popup dimensions should just be determined by what you wish the size of the popup to be initially.
To determine your layout width, select every object on the layout using cmd+A (ctrl+A) and in the inspector/object info panel, look for the right coordinate.
If you only ever use one platform, you can skip using the custom function and directly set your window width & height. To do this, open the popup window in browse mode & resize to fit, using your data viewer, obtain the values of Get(WindowLeft) and Get(WindowTop) functions respectively.
Putting it all together
All the required components are now known, and we can create the window, set it up, and move it back on-screen when ready.
The script above sets the required coordinates and dimensions of the new window. The window is created off-screen. Then follows the setup of the window, in this case switching to the desired layout. Finally, the window is moved back into its exact correct location using Move/Resize window.
Aligning popups relative to a layout object
The last type of popup I will be dealing with is those that are to be initially positioned relative to a layout object. Whereas the center-aligned method uses the dimensions of the current window, this will use the dimensions and coordinates of a layout object.
Again, two custom functions have been produced to assist in the correct positioning of the window, popup_ObjectLeft and popup_ObjectTop.
These functions take 3 parameters respectively:
-ObjectName - The object name of layout object to position relative to.
-Orientation - a keyword "top", "left", "bottom", or "right" to position popup.
-PopupWidth/Height - dimensions of popup depending on function used.
Again, not going into much detail about the functions, but just to say the functions make use of the GetLayoutObjectAttribute function to obtain coordinates & dimensions of the layout object, all information required to correctly determine the popups initial coordinates.
From here, once the coordinates are known, it's just a case of creating the window, setting it up, and then moving it back on screen as shown earlier.
A note about dock positioning on OS X
While writing this article I noticed a peculiar bug in FileMaker concerning obtaining a windows coordinates versus a layout objects coordinates. This is most apparent when your os x dock is positioned on the left edge of your screen.
In the picture above, my dock is on the left edge of my screen. You can see the left coordinate of the window when positioned right beside the dock is 0 pixels. This would suggest that when the dock is on the left of screen, window coordinates begin from the edge of the dock, rather than the screen itself.
However this is not the case for left coordinates of layout objects. As you can see, the gap between the edge of the window and the object is 126 px. You would think that this would mean the left edge of the button would be 126 px, you would be wrong! The left edge is in fact 176 px, a full 50 pixels more. So it turns out that when obtaining object coordinates, they do in fact begin from the left edge of your screen, and not from the edge of the dock as a window coordinate will.
This causes some problems in determining a correct popup window position because you cannot determine in FileMaker whether your dock is on the bottom of screen, or on left of screen. The functions mentioned in this article are assuming that the dock is at the bottom of screen, and thus the window coordinates and the object coordinates use the same 0 pixel coordinate location.
If your dock is on left of screen, you will find that the left coordinate of the popup window is slightly offset to the right of the object when using the object-aligning technique. This can be modified in the functions themselves, but is not a good solution, as users can always change their dock location whenever they want.
Note that the coordinate bug is not a factor when center-aligning a popup in front of the parent window.
Final Thoughts:
If any database is to be taken seriously as a professional looking, polished solution, then care needs to be taken in how you create your popup windows. Unnecessary window flashing, resizing, or visual setup of a popup should be avoided, as it makes a database feel unpolished and even unfinished. Correct positioning of popups is not a difficult thing to do given the proper tools, and can go a long way to improving the usability of your solution.
Example File
Please find attached an example file. This file was used for all the screenshots in this article, and is provided to help you fully understand what is going on in this article, and to let you experiment in FileMaker with this solution.
Something to say? Post a comment...
Comments
Daniel Wood 25/08/2011 1:47pm (13 years ago)
Hi Alan,
Unfortunately as you have discovered, the Adjust Window [ Resize to Fit ] step causes the window to be moved back on-screen. It is for this reason in the article that we define the height and width precisely before generating the window. I would love to be able to do the resize to fit off-screen too, and would love to know any way around this :)
If you were attempting to make the script generic or modularize it then you could pass some of the information as parameters to script such as the object name, height, width etc. Sorry I can't be of more help on the issue, hopefully someone else can shed some light.
Alan 25/08/2011 1:38pm (13 years ago)
Daniel,
Was hoping you could take a look at the post I made at
http://filemakertoday.com/com/showthread.php/28943-Looking-at-WEETBICKS-quot-Creating-Tidy-Popup-Windows-quot?p=118194#post118194
Thanks
Alan
Rich Stuart 31/07/2011 6:37am (13 years ago)
Thanks for the great article! I hope I just implemented it correctly in my solution by "hard-coding" the height and width of the window under the " Establish the Popup Windows Width & Height" in the "Create Centred Pop-up" script; it appears to work well.
However... (There's _always_ a "however" :) )
I'm still dogged with the problem of a user using the zoom controls and having the pop-up window not resize accordingly, e.g., if the user bumps the zoom up to 150% the pop-up doesn't fit anymore as it was hard-coded for a zoom level of 100% ...and since there isn't a script step where you can insert step "Case( Zoom = 150 ); ...", we're stuck.
I suspect this is more of a FMP Wish List issue than anything else. :S
Cheers.
Robert Moran 08/06/2011 7:17am (14 years ago)
Question, can this technique be used for templates? I have a client that uses different templates keyed to specific tasks. The database works perfectly as does the related records that can be accessed via a value list to it's parent table. The problem is that certain fields will be used for one task while a different set will be used for another. I need to allow folks to pick a particular template without creating confusion that separate windows create because the parent table content does not change, only the template. Any help on this would be terrific.
Daniel Wood 24/05/2011 1:56pm (14 years ago)
Hi Paula, The issue here may be at which stage you are setting the left and top coordinates to use for your new window.
If you have a look in the example file for the centered window example, you'll notice the use of a couple of CF's called popup_Centerleft and popup_CenterTop. These functions actually make use of the GET window functions such as WindowHeight, WindowLeft, WindowTop etc...
If you call these custom functions from your second file, then when these functions evaluate, they will be obtaining window information from a window in your second file, not the first. If you want your window to appear centered in front of a window from your first file, then you will need to set $Top and $Left window coordinates prior to calling your script in your second file. This way, $Top and $Left will be based on your window in your first file, and the new window will be positioned centered in front of that one as you would expect.
Hope this helps, cheers.
Paula Sanchez 24/05/2011 2:22am (14 years ago)
I have a situation where the script begins in one file and carries over to another. I am passing the window width/height/top/left info. via parameters to the 2nd file and watching debugger to see that they are correct. The scripting and custom functions are all in the 2nd file. Still, using the 2 file model, I cannot acheive the centered result utilizing your custom function. I am not screen sharing, but the popup is sticking to the 0/0 (top/left) coordinates. I have always used a similar script in all of my files with great success. Any thoughts. I am baffled.
Daniel 13/01/2011 9:16am (14 years ago)
Thanks for the comments everyone. Fenton, I might just try that applescript & see how it goes, thanks.
HOnza Koudelka 13/01/2011 1:59am (14 years ago)
I always cared about window positioning when creating a new window and I still have a problem explaining my developers how important it is. The instant pop-up thanks to preparing the window's content off-screen is another good point. Great article! Thanks
Paul Spafford 11/01/2011 3:48pm (14 years ago)
I didn't know the dock could throw off your coordinates like that. Nastiness! Thanks for that, Daniel.
Fenton Jones 11/01/2011 10:10am (14 years ago)
You can get the oriention and tile size of the Dock via a Perform AppleScript script step. You would need to set these into global fields, best on a 1 record constants table. This can be done via a "startup" script, via File Options. The size of the Desktop itself can be gotten via the Get ( WindowDesktopWidth ) function.
-- keys may not exist if you've never moved the Dock, hence the "try / on error"
try
set orientation to do shell script "defaults read com.apple.dock orientation"
-- "right", key may not exist if you've never moved the Dock
on error
set orientation to "bottom"
end try
-- Don't know what the default tile size is, guessing 48
try
set tilesize to do shell script "defaults read com.apple.dock tilesize"
on error
set tilesize to 48
end try
--tell application "FileMaker Pro Advanced" -- not needed within FileMaker
tell table "Home" -- table occurrence name
set field "z_gDock_orientation" to orientation -- global fields
set field "z_gDock_tilesize" to tilesize
end tell
--end tell
Daniel 11/01/2011 9:02am (14 years ago)
That's a great point I hadn't thought of, thanks Jeremy :)
Jeremy Bante 11/01/2011 9:01am (14 years ago)
This is a great technique demonstration. Center-aligning pop-up windows with an existing window or specific layout objects is a great thing to do, but there's a better reason for it than just "polish." Users' foveal vision is a kind of center of visual attention, just big enough for the one thing you're looking at during any one instant. Visual feedback, like a pop-up window, is more affective at capturing focus if you can put it in the user's foveal vision. The best way to do that is to put the new window over where the user was already looking, which will invariably be on the button the user just clicked to start the script that created the window.
« previous 1 2
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments