• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How to make 'filter' child panels? [SOLVED -- sort of]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to make 'filter' child panels? [SOLVED -- sort of]


  • Subject: Re: How to make 'filter' child panels? [SOLVED -- sort of]
  • From: Cem Karan <email@hidden>
  • Date: Wed, 14 Feb 2007 10:00:52 -0500

Well, its been a few weeks of thinking and playing with code, and I figure I should tell everyone what I've figured out, just in case anyone else needs to do this. Reread the original message for an explanation of what I was working on (http://lists.apple.com/archives/ cocoa-dev/2007/Jan/msg00944.html), or the rest of this won't make any sense.

Short answer, it is possible, but while the window code is easy, keeping track of what to display is not.

Long answer, you are actually creating a new window server subsystem, and you will be required to keep track of all that is going on. In talking with Ryan Stevens, and in experimenting a little on my own, here are the kinds of problems I discovered:

1) There may be multiple parent windows, which may be overlapping each other. If these were photos and you were using a sheet of plastic to filter out some color, then you would expect that a filter that overlaps more than one photo would filter all photos below it. If two photos overlap, then you'll only see the one that is on top.

2) Filter windows may overlap each other, which leads to interesting questions; when does a filter window filter another filter window? To give a made-up example, imagine that you have something like an onion that is in layers. Each filter window you have peels away one layer. If you put two filter windows above each other, should they 'add' and remove two layers? This is important because of question 3.

3) What about mouse events and key events? Which window gets it? Imagine that you have an X-ray view into the inside of an object. When you click on the thing in the filter window, what you really want to do is manipulate the inside of the object 'owned' by the parent window. But if there are multiple layers of filters, and some provide things like dialog balloons, you may actually want to edit the dialog balloon that is in a lower layer. Thus, just passing the click through to the window below doesn't quite work, nor does grabbing it directly in the filter window.

To solve all of this, I decided to mimic what Apple already provides as much as possible. Note that my solution is 1) incomplete and 2) horribly slow and unoptimized.

First off, starting with the easy part, making semi-transparent windows, I figured out what Matt Gemmell was doing in his code (see the original message for where to get it), and figured out how I was going to synchronize a filter window's contents with some other window. I made a scrollview that was the child of the filter panel. To calculate the size of the scrollview, I first calculate the minimum size rect to completely encompass all monitors attached to the system (see below). Then set the scrollview size to be twice that height, and 3 times that width. When the filter panel moves, you programmatically move the scrollview in the opposite direction, making the contents of the scrollview appear to remain motionless.

If that was all there was to it, then you'd just need a scrollview that was the size of that minimum encompassing rect. The problem is that it is possible move the parent windows completely off the screen. Fortunately, the biggest you can make a single window is the size of the encompassing rect, and the furthest you can move it is off the screen to the left or right, or drag it all the way down (I haven't run into a case where you can manually push a window up above the menu bar, if I do, I'll just extend the scrollview upwards). That is the reason for the size of the scrollview.

+-------------+----------------+
|\\\\\\\\\\\\\|                |
|\\\\\\\\\\\\\|                |
+-------------+    Monitor 1   |
|             |                |
|  Monitor 2  |                |
|             +----------------+
|             |\\\\\\\\\\\\\\\\|
+-------------+----------------|

Within the scrollview, I draw NSImages that I prepare offscreen. These images can be moved wherever I need via a simple translation, which is how I handle the movement of parent windows. Now, because of how people expect objects to interact, I'm able to cut down on drawing and processing time quite a bit when windows are moved. When you move a window in my app, it will always be made key and ordered to the front. No-one psychologically expects a filter to filter something above it, only things that are below it. Thus, until the window stops moving, and a filter is above it, I don't have to calculate any affine transforms, which, when there are many different filter windows up at once, can save some time. One thing I have not tried (which I should) is to calculate the offscreen affine transforms of all filter window images as soon as a parent window is dropped. The general usage pattern seems to be to move a window, drop it, then grab a filter and look at the window that was just dropped.

Now, all of that said, the really hard part is deciding which data to display. I really haven't come up with a good general solution to this, mostly because of the use cases and requests that I keep getting, but here is the hack that I have so far. Note that quite a bit of this is planning work, but my experiments seem to suggest it will work, so if you see something wrong, go ahead and holler.

Filter windows, parent windows, etc. are all flat; no filter window is a child of any other window. This was the only way that I could solve the problem of a filter window overlapping two parent windows. All filter windows listen for movement and resize notifications from all parent windows. Thus, whenever a new parent window is created or destroyed, I have to update all filter window's notification mechanisms. If a filter window is able to show information from another filter window, then they will both listen to notifications from each other. Each window and filter window draws its information from a single central store, which has 'layers' associated with it (call them dimensions, or columns in a database, or whatever you want). There is also a central controller that keeps track of the ordering of windows (does anyone know of a better way of doing this???). When a window's data changes, the controller notifies that window and all windows that are ordered above it that a change occurred. Each window will then check the store to see what new image information needs to be calculated, if any.

I have no idea if this method will work or not, I haven't implemented the whole data store concept yet, and if there are dozens of filter windows that need to be updated at one time, I'm sure that it will cause a massive headache. On paper, and with a couple of scratch tests, it looks good though.

Hope this helps someone else, sorry about the length of this message,
Cem Karan
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Prev by Date: RE: Cocoa-Java : how to manage multiple windows, dinamic windows and open/save dialog
  • Next by Date: Abusing Core Data for fun and profit.
  • Previous by thread: Re: Cocoa-Java : how to manage multiple windows, dinamic windows and open/save dialog
  • Next by thread: Abusing Core Data for fun and profit.
  • Index(es):
    • Date
    • Thread