72
73 public static final String WINDOW_ALPHA = "Window.alpha";
74 public static final String WINDOW_SHADOW = "Window.shadow";
75
76 public static final String WINDOW_STYLE = "Window.style";
77 public static final String WINDOW_SHADOW_REVALIDATE_NOW = "apple.awt.windowShadow.revalidateNow";
78
79 public static final String WINDOW_DOCUMENT_MODIFIED = "Window.documentModified";
80 public static final String WINDOW_DOCUMENT_FILE = "Window.documentFile";
81
82 public static final String WINDOW_CLOSEABLE = "Window.closeable";
83 public static final String WINDOW_MINIMIZABLE = "Window.minimizable";
84 public static final String WINDOW_ZOOMABLE = "Window.zoomable";
85 public static final String WINDOW_HIDES_ON_DEACTIVATE="Window.hidesOnDeactivate";
86
87 public static final String WINDOW_DOC_MODAL_SHEET = "apple.awt.documentModalSheet";
88 public static final String WINDOW_FADE_DELEGATE = "apple.awt._windowFadeDelegate";
89 public static final String WINDOW_FADE_IN = "apple.awt._windowFadeIn";
90 public static final String WINDOW_FADE_OUT = "apple.awt._windowFadeOut";
91 public static final String WINDOW_FULLSCREENABLE = "apple.awt.fullscreenable";
92
93
94 // Yeah, I know. But it's easier to deal with ints from JNI
95 static final int MODELESS = 0;
96 static final int DOCUMENT_MODAL = 1;
97 static final int APPLICATION_MODAL = 2;
98 static final int TOOLKIT_MODAL = 3;
99
100 // window style bits
101 static final int _RESERVED_FOR_DATA = 1 << 0;
102
103 // corresponds to native style mask bits
104 static final int DECORATED = 1 << 1;
105 static final int TEXTURED = 1 << 2;
106 static final int UNIFIED = 1 << 3;
107 static final int UTILITY = 1 << 4;
108 static final int HUD = 1 << 5;
109 static final int SHEET = 1 << 6;
110
111 static final int CLOSEABLE = 1 << 7;
175 new Property<CPlatformWindow>(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
176 nativeRevalidateNSWindowShadow(c.getNSWindowPtr());
177 }},
178 new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
179 if (value == null || !(value instanceof java.io.File)) {
180 nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), null);
181 return;
182 }
183
184 final String filename = ((java.io.File)value).getAbsolutePath();
185 nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), filename);
186 }}
187 }) {
188 public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
189 Component root = SwingUtilities.getRoot(p);
190 if (root == null || (LWWindowPeer)root.getPeer() == null) return null;
191 return (CPlatformWindow)((LWWindowPeer)root.getPeer()).getPlatformWindow();
192 }
193 };
194
195 // Bounds of the native widget but in the Java coordinate system.
196 // In order to keep it up-to-date we will update them on
197 // 1) setting native bounds via nativeSetBounds() call
198 // 2) getting notification from the native level via deliverMoveResizeEvent()
199 private Rectangle nativeBounds;
200 private volatile boolean isFullScreenMode = false;
201
202 private Window target;
203 private LWWindowPeer peer;
204 private CPlatformView contentView;
205 private CPlatformWindow owner;
206
207 public CPlatformWindow(final PeerType peerType) {
208 super(0, true);
209 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
210 }
211
212 /*
213 * Delegate initialization (create native window and all the
214 * related resources).
215 */
216 @Override // PlatformWindow
217 public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
218 this.peer = _peer;
219 this.target = _target;
220 if (_owner instanceof CPlatformWindow) {
364
365 prop = rootpane.getClientProperty(WINDOW_SHADOW);
366 if (prop != null) {
367 styleBits = SET(styleBits, HAS_SHADOW, Boolean.parseBoolean(prop.toString()));
368 }
369
370 prop = rootpane.getClientProperty(WINDOW_DRAGGABLE_BACKGROUND);
371 if (prop != null) {
372 styleBits = SET(styleBits, DRAGGABLE_BACKGROUND, Boolean.parseBoolean(prop.toString()));
373 }
374 }
375
376 return styleBits;
377 }
378
379 // this is the counter-point to -[CWindow _nativeSetStyleBit:]
380 protected void setStyleBits(final int mask, final boolean value) {
381 nativeSetNSWindowStyleBits(getNSWindowPtr(), mask, value ? mask : 0);
382 }
383
384 private native void _toggleFullScreenMode(final long model);
385
386 public void toggleFullScreen() {
387 _toggleFullScreenMode(getNSWindowPtr());
388 }
389
390 @Override // PlatformWindow
391 public void setMenuBar(MenuBar mb) {
392 final long nsWindowPtr = getNSWindowPtr();
393 CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
394 if (mbPeer != null) {
395 nativeSetNSWindowMenuBar(nsWindowPtr, mbPeer.getModel());
396 } else {
397 nativeSetNSWindowMenuBar(nsWindowPtr, 0);
398 }
399 }
400
401 @Override // PlatformWindow
402 public Image createBackBuffer() {
403 return contentView.createBackBuffer();
404 }
405
406 @Override // PlatformWindow
407 public void dispose() {
408 if (owner != null) {
409 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
637
638 @Override
639 public void setAlwaysOnTop(boolean isAlwaysOnTop) {
640 setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
641 }
642
643 @Override
644 public void setOpacity(float opacity) {
645 CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
646 }
647
648 @Override
649 public void setOpaque(boolean isOpaque) {
650 CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
651 if (!isOpaque) {
652 long clearColor = CWrapper.NSColor.clearColor();
653 CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
654 }
655 }
656
657 @Override
658 public void enterFullScreenMode() {
659 isFullScreenMode = true;
660 contentView.enterFullScreenMode(getNSWindowPtr());
661 }
662
663 @Override
664 public void exitFullScreenMode() {
665 contentView.exitFullScreenMode();
666 isFullScreenMode = false;
667 }
668
669 @Override
670 public void setWindowState(int windowState) {
671 if (!peer.isVisible()) {
672 // setVisible() applies the state
673 return;
674 }
675
676 int prevWindowState = peer.getState();
677 if (prevWindowState == windowState) return;
678
679 final long nsWindowPtr = getNSWindowPtr();
680 switch (windowState) {
681 case Frame.ICONIFIED:
682 if (prevWindowState == Frame.MAXIMIZED_BOTH) {
683 // let's return into the normal states first
684 // the zoom call toggles between the normal and the max states
685 CWrapper.NSWindow.zoom(nsWindowPtr);
686 }
687 CWrapper.NSWindow.miniaturize(nsWindowPtr);
746 @Override
747 public long getLayerPtr() {
748 return contentView.getWindowLayerPtr();
749 }
750
751 private void validateSurface() {
752 SurfaceData surfaceData = getSurfaceData();
753 if (surfaceData instanceof CGLSurfaceData) {
754 ((CGLSurfaceData)surfaceData).validate();
755 }
756 }
757
758 /*************************************************************
759 * Callbacks from the AWTWindow and AWTView objc classes.
760 *************************************************************/
761 private void deliverWindowFocusEvent(boolean gained){
762 peer.notifyActivation(gained);
763 }
764
765 private void deliverMoveResizeEvent(int x, int y, int width, int height) {
766 // when the content view enters the full-screen mode, the native
767 // move/resize notifications contain a bounds smaller than
768 // the whole screen and therefore we ignore the native notifications
769 // and the content view itself creates correct synthetic notifications
770 if (isFullScreenMode) return;
771
772 nativeBounds = new Rectangle(x, y, width, height);
773 peer.notifyReshape(x, y, width, height);
774 //TODO validateSurface already called from notifyReshape
775 validateSurface();
776 }
777
778 private void deliverWindowClosingEvent() {
779 if (peer.getBlocker() == null) {
780 peer.postEvent(new WindowEvent(target, WindowEvent.WINDOW_CLOSING));
781 }
782 }
783
784 private void deliverIconify(final boolean iconify) {
785 peer.notifyIconify(iconify);
786 }
787
788 private void deliverZoom(final boolean isZoomed) {
789 peer.notifyZoom(isZoomed);
790 }
791
|
72
73 public static final String WINDOW_ALPHA = "Window.alpha";
74 public static final String WINDOW_SHADOW = "Window.shadow";
75
76 public static final String WINDOW_STYLE = "Window.style";
77 public static final String WINDOW_SHADOW_REVALIDATE_NOW = "apple.awt.windowShadow.revalidateNow";
78
79 public static final String WINDOW_DOCUMENT_MODIFIED = "Window.documentModified";
80 public static final String WINDOW_DOCUMENT_FILE = "Window.documentFile";
81
82 public static final String WINDOW_CLOSEABLE = "Window.closeable";
83 public static final String WINDOW_MINIMIZABLE = "Window.minimizable";
84 public static final String WINDOW_ZOOMABLE = "Window.zoomable";
85 public static final String WINDOW_HIDES_ON_DEACTIVATE="Window.hidesOnDeactivate";
86
87 public static final String WINDOW_DOC_MODAL_SHEET = "apple.awt.documentModalSheet";
88 public static final String WINDOW_FADE_DELEGATE = "apple.awt._windowFadeDelegate";
89 public static final String WINDOW_FADE_IN = "apple.awt._windowFadeIn";
90 public static final String WINDOW_FADE_OUT = "apple.awt._windowFadeOut";
91 public static final String WINDOW_FULLSCREENABLE = "apple.awt.fullscreenable";
92 public static final String WINDOW_MENU_VISIBLE_IN_FULLSCREEN = "apple.awt.menuVisibleInFullscreen";
93
94
95 // Yeah, I know. But it's easier to deal with ints from JNI
96 static final int MODELESS = 0;
97 static final int DOCUMENT_MODAL = 1;
98 static final int APPLICATION_MODAL = 2;
99 static final int TOOLKIT_MODAL = 3;
100
101 // window style bits
102 static final int _RESERVED_FOR_DATA = 1 << 0;
103
104 // corresponds to native style mask bits
105 static final int DECORATED = 1 << 1;
106 static final int TEXTURED = 1 << 2;
107 static final int UNIFIED = 1 << 3;
108 static final int UTILITY = 1 << 4;
109 static final int HUD = 1 << 5;
110 static final int SHEET = 1 << 6;
111
112 static final int CLOSEABLE = 1 << 7;
176 new Property<CPlatformWindow>(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
177 nativeRevalidateNSWindowShadow(c.getNSWindowPtr());
178 }},
179 new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
180 if (value == null || !(value instanceof java.io.File)) {
181 nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), null);
182 return;
183 }
184
185 final String filename = ((java.io.File)value).getAbsolutePath();
186 nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), filename);
187 }}
188 }) {
189 public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
190 Component root = SwingUtilities.getRoot(p);
191 if (root == null || (LWWindowPeer)root.getPeer() == null) return null;
192 return (CPlatformWindow)((LWWindowPeer)root.getPeer()).getPlatformWindow();
193 }
194 };
195
196 private final Object LOCK = new Object(){};
197
198 // Bounds of the native widget but in the Java coordinate system.
199 // In order to keep it up-to-date we will update them on
200 // 1) setting native bounds via nativeSetBounds() call
201 // 2) getting notification from the native level via deliverMoveResizeEvent()
202 private Rectangle nativeBounds;
203
204 private boolean isFullScreenMode = false; // synchronized on the LOCK
205
206 private Window target;
207 private LWWindowPeer peer;
208 private CPlatformView contentView;
209 private CPlatformWindow owner;
210
211 public CPlatformWindow(final PeerType peerType) {
212 super(0, true);
213 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
214 }
215
216 /*
217 * Delegate initialization (create native window and all the
218 * related resources).
219 */
220 @Override // PlatformWindow
221 public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
222 this.peer = _peer;
223 this.target = _target;
224 if (_owner instanceof CPlatformWindow) {
368
369 prop = rootpane.getClientProperty(WINDOW_SHADOW);
370 if (prop != null) {
371 styleBits = SET(styleBits, HAS_SHADOW, Boolean.parseBoolean(prop.toString()));
372 }
373
374 prop = rootpane.getClientProperty(WINDOW_DRAGGABLE_BACKGROUND);
375 if (prop != null) {
376 styleBits = SET(styleBits, DRAGGABLE_BACKGROUND, Boolean.parseBoolean(prop.toString()));
377 }
378 }
379
380 return styleBits;
381 }
382
383 // this is the counter-point to -[CWindow _nativeSetStyleBit:]
384 protected void setStyleBits(final int mask, final boolean value) {
385 nativeSetNSWindowStyleBits(getNSWindowPtr(), mask, value ? mask : 0);
386 }
387
388 @Override // PlatformWindow
389 public void setMenuBar(MenuBar mb) {
390 final long nsWindowPtr = getNSWindowPtr();
391 CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
392 if (mbPeer != null) {
393 nativeSetNSWindowMenuBar(nsWindowPtr, mbPeer.getModel());
394 } else {
395 nativeSetNSWindowMenuBar(nsWindowPtr, 0);
396 }
397 }
398
399 @Override // PlatformWindow
400 public Image createBackBuffer() {
401 return contentView.createBackBuffer();
402 }
403
404 @Override // PlatformWindow
405 public void dispose() {
406 if (owner != null) {
407 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
635
636 @Override
637 public void setAlwaysOnTop(boolean isAlwaysOnTop) {
638 setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
639 }
640
641 @Override
642 public void setOpacity(float opacity) {
643 CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
644 }
645
646 @Override
647 public void setOpaque(boolean isOpaque) {
648 CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
649 if (!isOpaque) {
650 long clearColor = CWrapper.NSColor.clearColor();
651 CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
652 }
653 }
654
655 private void setMenuBarVisibleIfOnPrimaryScreen(boolean visible) {
656 long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
657 try {
658 long primaryScreen = CWrapper.NSScreen.screens(0);
659 try {
660 if (primaryScreen == screen) {
661 CWrapper.NSMenu.setMenuBarVisible(visible);
662 }
663 } finally {
664 CWrapper.NSObject.release(primaryScreen);
665 }
666 } finally {
667 CWrapper.NSObject.release(screen);
668 }
669 }
670
671 // Used from com.apple.eawt.Application.requestToggleFullScreen()
672 public void toggleFullScreen() {
673 synchronized (LOCK) {
674 if (isFullScreenMode) {
675 enterFullScreenMode();
676 } else {
677 exitFullScreenMode();
678 }
679 }
680 }
681
682 @Override
683 public void enterFullScreenMode() {
684 synchronized (LOCK) {
685 if (!isFullScreenMode) {
686 isFullScreenMode = true;
687 boolean hideMenuBar = true;
688
689 if (target instanceof javax.swing.RootPaneContainer) {
690 javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane();
691 Object prop = rootpane.getClientProperty(WINDOW_MENU_VISIBLE_IN_FULLSCREEN);
692 if (prop != null) {
693 if (Boolean.parseBoolean(prop.toString())) {
694 hideMenuBar = false;
695 }
696 }
697 }
698
699 if (hideMenuBar) {
700 setMenuBarVisibleIfOnPrimaryScreen(false);
701 }
702 CWrapper.NSWindow.toggleFullScreen(getNSWindowPtr(), 0L);
703 }
704 }
705 }
706
707 @Override
708 public void exitFullScreenMode() {
709 synchronized (LOCK) {
710 if (isFullScreenMode) {
711 CWrapper.NSWindow.toggleFullScreen(getNSWindowPtr(), 0L);
712 setMenuBarVisibleIfOnPrimaryScreen(true);
713 isFullScreenMode = false;
714 }
715 }
716 }
717
718 @Override
719 public void setWindowState(int windowState) {
720 if (!peer.isVisible()) {
721 // setVisible() applies the state
722 return;
723 }
724
725 int prevWindowState = peer.getState();
726 if (prevWindowState == windowState) return;
727
728 final long nsWindowPtr = getNSWindowPtr();
729 switch (windowState) {
730 case Frame.ICONIFIED:
731 if (prevWindowState == Frame.MAXIMIZED_BOTH) {
732 // let's return into the normal states first
733 // the zoom call toggles between the normal and the max states
734 CWrapper.NSWindow.zoom(nsWindowPtr);
735 }
736 CWrapper.NSWindow.miniaturize(nsWindowPtr);
795 @Override
796 public long getLayerPtr() {
797 return contentView.getWindowLayerPtr();
798 }
799
800 private void validateSurface() {
801 SurfaceData surfaceData = getSurfaceData();
802 if (surfaceData instanceof CGLSurfaceData) {
803 ((CGLSurfaceData)surfaceData).validate();
804 }
805 }
806
807 /*************************************************************
808 * Callbacks from the AWTWindow and AWTView objc classes.
809 *************************************************************/
810 private void deliverWindowFocusEvent(boolean gained){
811 peer.notifyActivation(gained);
812 }
813
814 private void deliverMoveResizeEvent(int x, int y, int width, int height) {
815 nativeBounds = new Rectangle(x, y, width, height);
816 peer.notifyReshape(x, y, width, height);
817 //TODO validateSurface already called from notifyReshape
818 validateSurface();
819 }
820
821 private void deliverWindowClosingEvent() {
822 if (peer.getBlocker() == null) {
823 peer.postEvent(new WindowEvent(target, WindowEvent.WINDOW_CLOSING));
824 }
825 }
826
827 private void deliverIconify(final boolean iconify) {
828 peer.notifyIconify(iconify);
829 }
830
831 private void deliverZoom(final boolean isZoomed) {
832 peer.notifyZoom(isZoomed);
833 }
834
|