1/*
2    PPGNUstepGlue_PopupPanelHidingOnWindowMove.m
3
4    Copyright 2014-2018 Josh Freeman
5    http://www.twilightedge.com
6
7    This file is part of PikoPixel for GNUstep.
8    PikoPixel is a graphical application for drawing & editing pixel-art images.
9
10    PikoPixel is free software: you can redistribute it and/or modify it under
11    the terms of the GNU Affero General Public License as published by the
12    Free Software Foundation, either version 3 of the License, or (at your
13    option) any later version approved for PikoPixel by its copyright holder (or
14    an authorized proxy).
15
16    PikoPixel is distributed in the hope that it will be useful, but WITHOUT ANY
17    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18    FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19    details.
20
21    You should have received a copy of the GNU Affero General Public License
22    along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#ifdef GNUSTEP
26
27#import <Cocoa/Cocoa.h>
28#import "NSObject_PPUtilities.h"
29#import "PPAppBootUtilities.h"
30#import "PPDocumentWindowController.h"
31#import "PPPopupPanelsController.h"
32#import "PPSamplerImagePopupPanelController.h"
33
34
35static int gNumBlocksOnPopupPanelHiding = 0;
36
37
38@interface PPDocumentWindowController (PPGNUstepGlue_PopupPanelHidingOnWindowMoveUtilities)
39
40+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_Block;
41
42+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_Unblock;
43
44+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_UnblockFromNewStackFrame;
45
46@end
47
48
49@implementation NSObject (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
50
51+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_InstallPatches
52{
53    macroSwizzleInstanceMethod(PPDocumentWindowController, handleNSWindowNotification_WillMove:,
54                                ppGSPatch_HandleNSWindowNotification_WillMove:);
55
56
57    macroSwizzleInstanceMethod(PPPopupPanelsController, setActivePopupPanel:,
58                                ppGSPatch_PopupPanelHidingOnWindowMove_SetActivePopupPanel:);
59
60
61    macroSwizzleInstanceMethod(PPSamplerImagePopupPanelController, windowWillResize:toSize:,
62                                ppGSPatch_WindowWillResize:toSize:);
63
64
65    macroSwizzleClassMethod(NSColorPanel, dragColor:withEvent:fromView:,
66                                ppGSPatch_DragColor:withEvent:fromView:);
67
68
69    macroSwizzleInstanceMethod(NSPopUpButtonCell, attachPopUpWithFrame:inView:,
70                                ppGSPatch_AttachPopUpWithFrame:inView:);
71}
72
73+ (void) load
74{
75    macroPerformNSObjectSelectorAfterAppLoads(
76                                        ppGSGlue_PopupPanelHidingOnWindowMove_InstallPatches);
77}
78
79@end
80
81@implementation PPDocumentWindowController (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
82
83- (void) ppGSPatch_HandleNSWindowNotification_WillMove: (NSNotification *) notification
84{
85    if (gNumBlocksOnPopupPanelHiding > 0)
86    {
87        return;
88    }
89
90    [self ppGSPatch_HandleNSWindowNotification_WillMove: notification];
91}
92
93@end
94
95@implementation PPPopupPanelsController (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
96
97- (void) ppGSPatch_PopupPanelHidingOnWindowMove_SetActivePopupPanel:
98                                                            (PPPopupPanelType) popupPanelType
99{
100    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Block];
101
102    [self ppGSPatch_PopupPanelHidingOnWindowMove_SetActivePopupPanel: popupPanelType];
103
104    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_UnblockFromNewStackFrame];
105}
106
107@end
108
109@implementation PPSamplerImagePopupPanelController (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
110
111- (NSSize) ppGSPatch_WindowWillResize: (NSWindow *) sender toSize: (NSSize) proposedFrameSize
112{
113    NSSize newWindowSize;
114
115    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Block];
116
117    newWindowSize = [self ppGSPatch_WindowWillResize: sender toSize: proposedFrameSize];
118
119    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_UnblockFromNewStackFrame];
120
121    return newWindowSize;
122}
123
124@end
125
126@implementation NSColorPanel (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
127
128+ (BOOL) ppGSPatch_DragColor: (NSColor *) aColor
129            withEvent: (NSEvent *) anEvent
130            fromView: (NSView *) sourceView
131{
132    BOOL returnVal;
133
134    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Block];
135
136    returnVal = [self ppGSPatch_DragColor: aColor withEvent: anEvent fromView: sourceView];
137
138    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Unblock];
139
140    return returnVal;
141}
142
143@end
144
145@implementation NSPopUpButtonCell (PPGNUstepGlue_PopupPanelHidingOnWindowMove)
146
147- (void) ppGSPatch_AttachPopUpWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
148{
149    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Block];
150
151    [self ppGSPatch_AttachPopUpWithFrame: cellFrame inView: controlView];
152
153    [PPDocumentWindowController ppGSGlue_PopupPanelHidingOnWindowMove_Unblock];
154}
155
156@end
157
158@implementation PPDocumentWindowController (PPGNUstepGlue_PopupPanelHidingOnWindowMoveUtilities)
159
160+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_Block
161{
162    gNumBlocksOnPopupPanelHiding++;
163}
164
165+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_Unblock
166{
167    gNumBlocksOnPopupPanelHiding--;
168}
169
170+ (void) ppGSGlue_PopupPanelHidingOnWindowMove_UnblockFromNewStackFrame
171{
172    [self ppPerformSelectorFromNewStackFrame:
173                                    @selector(ppGSGlue_PopupPanelHidingOnWindowMove_Unblock)];
174}
175
176@end
177
178#endif  // GNUSTEP
179
180