aboutsummaryrefslogtreecommitdiff
path: root/AppKit/GTMWindowSheetController.h
blob: 558814e77eb5d3e8f9e1106a8c6ce67f90ee34ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//
//  GTMWindowSheetController.h
//
//  Copyright 2009 Google Inc.
//
//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
//  use this file except in compliance with the License.  You may obtain a copy
//  of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
//  License for the specific language governing permissions and limitations under
//  the License.
//

#import <Cocoa/Cocoa.h>

// A class to manage multiple sheets for a window. Use it for tab-style
// interfaces, where each tab might need its own sheet.
//
// While Cocoa can send notifications for when views resize, it does not do so
// for views appearing/disappearing. The owner is responsible for calling
// -setActiveView: appropriately as the visible views change.
//
// Notes on usage:
// - Cocoa isn't used to sheets being (ab)used in the way we use them here and
//   makes sure we know it by providing slight visual anomalies like showing the
//   close box as disabled but not actually disabling it, and not showing
//   shadows for sheets. That's something you'll have to live with.
// - YOU are responsible for making sure that all sheets are closed before
//   the windows containing them closes. That means:
//   - You MUST implement the window delegate method -windowShouldClose: for any
//     window using this class. In it, call -viewsWithAttachedSheets to see if
//     there are any views with sheets attached to them. If there are, switch to
//     that view and do not allow the window to close.
//   - You MUST implement GTMWindowSheetControllerDelegate's method
//     -gtm_systemRequestsVisibilityForView:. When that method is called, the
//     system is trying to quit but realizes that there is a sheet on a window
//     that prevents it from doing so. In such a case, switch to that view.
//     (The quit is already prevented from happening so you don't need to worry
//     about it.)
//   - You MUST implement the application delegate method
//     -applicationShouldTerminate:. In it, for every window that might have a
//     sheet, call -viewsWithAttachedSheets to see if there are any views with
//     sheets attached to them. If there are, switch to that view and do not
//     allow the application to quit.
//   I hope you see a pattern here.

@protocol GTMWindowSheetControllerDelegate
- (void)gtm_systemRequestsVisibilityForView:(NSView*)view;
@end


@interface GTMWindowSheetController : NSObject {
 @private
  __weak NSWindow* window_;
  __weak NSView* activeView_;
  __weak id <GTMWindowSheetControllerDelegate> delegate_;

  NSMutableDictionary* sheets_;  // NSValue*(NSView*) -> SheetInfo*
}

// Initializes the class for use.
//
// Args:
//     window: The window for which to manage sheets. All views must be
//             contained by this window.
//   delegate: The delegate for this sheet controller.
//
- (id)initWithWindow:(NSWindow*)window
            delegate:(id <GTMWindowSheetControllerDelegate>)delegate;

// Starts a view modal session for a sheet. Intentionally similar to
// -[NSApplication beginSheet:modalForWindow:modalDelegate:didEndSelector:
//                contextInfo:].
//
// Args:
//            sheet: The window object representing the sheet you want to
//                   display.
//             view: The view object to which you want to attach the sheet.
//    modalDelegate: The delegate object that defines your didEndSelector
//                   method.
//   didEndSelector: The method on the modalDelegate that will be called when
//                   the sheet’s modal session has ended. This method must be
//                   defined on the object in the modalDelegate parameter and
//                   have the following signature:
//                     - (void)sheetDidEnd:(NSWindow *)sheet
//                              returnCode:(NSInteger)returnCode
//                             contextInfo:(void *)contextInfo;
//      contextInfo: A pointer to the context info you want passed to the
//                   didEndSelector method when the sheet’s modal session ends.
//
- (void)beginSheet:(NSWindow*)sheet
      modalForView:(NSView*)view
     modalDelegate:(id)modalDelegate
    didEndSelector:(SEL)didEndSelector
       contextInfo:(void *)contextInfo;

// Starts a view modal session for a system sheet. Just about any AppKit class
// that has an instance method named something like -beginSheetModalForWindow...
// will work with this method.
//
// Args:
//     systemSheet: The object that will show a sheet when triggered
//                  appropriately.
//            view: The view object to which you want to attach the sheet.
//   modalDelegate: The delegate object that defines your didEndSelector
//                  method.
//          params: The parameters of the -beginSheetModalForWindow... selector.
//                  For the parameter named "window", insert [NSNull null] into
//                  the array instead.
//
- (void)beginSystemSheet:(id)systemSheet
            modalForView:(NSView*)view
          withParameters:(NSArray*)params;

// Returns a BOOL value indicating whether the specified view has a sheet
// attached to it (hidden or not).
//
//  Args:
//    view: The view object to which a sheet might be attached.
//
//  Returns:
//    Whether or not a sheet is indeed attached to that view.
//
- (BOOL)isSheetAttachedToView:(NSView*)view;

// Returns a list of views that have sheets attached (hidden or not).
//
//  Returns:
//    An array of views that have sheets.
//
- (NSArray*)viewsWithAttachedSheets;

// Sets the specified view as active. The sheet (if there is one) for the active
// view is shown; sheets for all other views are hidden.
//
//  Args:
//    view: The view object to which a sheet is attached.
//
- (void)setActiveView:(NSView*)view;
@end