blob: c8ddd44dcaf72adb6a76cfc9ea3ef7658bad3eb4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.java.swing.plaf.motif;
27
28import javax.swing.*;
29import java.awt.Rectangle;
30import java.awt.Dimension;
31import java.awt.Insets;
32import java.awt.Color;
33import java.awt.Graphics;
34import java.awt.Component;
35import java.awt.Point;
36import javax.swing.plaf.*;
37import java.io.Serializable;
38
39/**
40 * <p>
41 * <strong>Warning:</strong>
42 * Serialized objects of this class will not be compatible with
43 * future Swing releases. The current serialization support is appropriate
44 * for short term storage or RMI between applications running the same
45 * version of Swing. A future release of Swing will provide support for
46 * long term persistence.
47 *
48 * @author David Kloba
49 */
50public class MotifDesktopPaneUI extends javax.swing.plaf.basic.BasicDesktopPaneUI
51{
52
53/// DesktopPaneUI methods
54 public static ComponentUI createUI(JComponent d) {
55 return new MotifDesktopPaneUI();
56 }
57
58 public MotifDesktopPaneUI() {
59 }
60
61 protected void installDesktopManager() {
62 desktopManager = desktop.getDesktopManager();
63 if(desktopManager == null) {
64 desktopManager = new MotifDesktopManager();
65 desktop.setDesktopManager(desktopManager);
66 ((MotifDesktopManager)desktopManager).adjustIcons(desktop);
67 }
68 }
69
70 public Insets getInsets(JComponent c) {return new Insets(0,0,0,0);}
71
72////////////////////////////////////////////////////////////////////////////////////
73/// DragPane class
74////////////////////////////////////////////////////////////////////////////////////
75 private class DragPane extends JComponent {
76 public void paint(Graphics g) {
77 g.setColor(Color.darkGray);
78 g.drawRect(0, 0, getWidth()-1, getHeight()-1);
79 }
80 };
81
82////////////////////////////////////////////////////////////////////////////////////
83/// MotifDesktopManager class
84////////////////////////////////////////////////////////////////////////////////////
85 private class MotifDesktopManager extends DefaultDesktopManager implements Serializable, UIResource {
86 JComponent dragPane;
87 boolean usingDragPane = false;
88 private transient JLayeredPane layeredPaneForDragPane;
89 int iconWidth, iconHeight;
90
91 // PENDING(klobad) this should be optimized
92 public void setBoundsForFrame(JComponent f, int newX, int newY,
93 int newWidth, int newHeight) {
94 if(!usingDragPane) {
95 boolean didResize;
96 didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight);
97 Rectangle r = f.getBounds();
98 f.setBounds(newX, newY, newWidth, newHeight);
99 SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r);
100 f.getParent().repaint(r.x, r.y, r.width, r.height);
101 if(didResize) {
102 f.validate();
103 }
104 } else {
105 Rectangle r = dragPane.getBounds();
106 dragPane.setBounds(newX, newY, newWidth, newHeight);
107 SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r);
108 dragPane.getParent().repaint(r.x, r.y, r.width, r.height);
109 }
110 }
111
112 public void beginDraggingFrame(JComponent f) {
113 usingDragPane = false;
114 if(f.getParent() instanceof JLayeredPane) {
115 if(dragPane == null)
116 dragPane = new DragPane();
117 layeredPaneForDragPane = (JLayeredPane)f.getParent();
118 layeredPaneForDragPane.setLayer(dragPane, Integer.MAX_VALUE);
119 dragPane.setBounds(f.getX(), f.getY(), f.getWidth(), f.getHeight());
120 layeredPaneForDragPane.add(dragPane);
121 usingDragPane = true;
122 }
123 }
124
125 public void dragFrame(JComponent f, int newX, int newY) {
126 setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
127 }
128
129 public void endDraggingFrame(JComponent f) {
130 if(usingDragPane) {
131 layeredPaneForDragPane.remove(dragPane);
132 usingDragPane = false;
133 if (f instanceof JInternalFrame) {
134 setBoundsForFrame(f, dragPane.getX(), dragPane.getY(),
135 dragPane.getWidth(), dragPane.getHeight());
136 } else if (f instanceof JInternalFrame.JDesktopIcon) {
137 adjustBoundsForIcon((JInternalFrame.JDesktopIcon)f,
138 dragPane.getX(), dragPane.getY());
139 }
140 }
141 }
142
143 public void beginResizingFrame(JComponent f, int direction) {
144 usingDragPane = false;
145 if(f.getParent() instanceof JLayeredPane) {
146 if(dragPane == null)
147 dragPane = new DragPane();
148 JLayeredPane p = (JLayeredPane)f.getParent();
149 p.setLayer(dragPane, Integer.MAX_VALUE);
150 dragPane.setBounds(f.getX(), f.getY(),
151 f.getWidth(), f.getHeight());
152 p.add(dragPane);
153 usingDragPane = true;
154 }
155 }
156
157 public void resizeFrame(JComponent f, int newX, int newY,
158 int newWidth, int newHeight) {
159 setBoundsForFrame(f, newX, newY, newWidth, newHeight);
160 }
161
162 public void endResizingFrame(JComponent f) {
163 if(usingDragPane) {
164 JLayeredPane p = (JLayeredPane)f.getParent();
165 p.remove(dragPane);
166 usingDragPane = false;
167 setBoundsForFrame(f, dragPane.getX(), dragPane.getY(),
168 dragPane.getWidth(), dragPane.getHeight());
169 }
170 }
171
172 public void iconifyFrame(JInternalFrame f) {
173 JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
174 Point p = icon.getLocation();
175 adjustBoundsForIcon(icon, p.x, p.y);
176 super.iconifyFrame(f);
177 }
178
179 /**
180 * Change positions of icons in the desktop pane so that
181 * they do not overlap
182 */
183 protected void adjustIcons(JDesktopPane desktop) {
184 // We need to know Motif icon size
185 JInternalFrame.JDesktopIcon icon = new JInternalFrame.JDesktopIcon(
186 new JInternalFrame());
187 Dimension iconSize = icon.getPreferredSize();
188 iconWidth = iconSize.width;
189 iconHeight = iconSize.height;
190
191 JInternalFrame[] frames = desktop.getAllFrames();
192 for (int i=0; i<frames.length; i++) {
193 icon = frames[i].getDesktopIcon();
194 Point ip = icon.getLocation();
195 adjustBoundsForIcon(icon, ip.x, ip.y);
196 }
197 }
198
199 /**
200 * Change positions of icon so that it doesn't overlap
201 * other icons.
202 */
203 protected void adjustBoundsForIcon(JInternalFrame.JDesktopIcon icon,
204 int x, int y) {
205 JDesktopPane c = icon.getDesktopPane();
206
207 int maxy = c.getHeight();
208 int w = iconWidth;
209 int h = iconHeight;
210 c.repaint(x, y, w, h);
211 x = x < 0 ? 0 : x;
212 y = y < 0 ? 0 : y;
213
214 /* Fix for disappearing icons. If the y value is maxy then this
215 * algorithm would place the icon in a non-displayed cell. Never
216 * to be ssen again.*/
217 y = y >= maxy ? (maxy - 1) : y;
218
219 /* Compute the offset for the cell we are trying to go in. */
220 int lx = (x / w) * w;
221 int ygap = maxy % h;
222 int ly = ((y-ygap) / h) * h + ygap;
223
224 /* How far are we into the cell we dropped the icon in. */
225 int dx = x - lx;
226 int dy = y - ly;
227
228 /* Set coordinates for the icon. */
229 x = dx < w/2 ? lx: lx + w;
230 y = dy < h/2 ? ly: ((ly + h) < maxy ? ly + h: ly);
231
232 while (getIconAt(c, icon, x, y) != null) {
233 x += w;
234 }
235
236 /* Cancel the move if the x value was moved off screen. */
237 if (x > c.getWidth()) {
238 return;
239 }
240 if (icon.getParent() != null) {
241 setBoundsForFrame(icon, x, y, w, h);
242 } else {
243 icon.setLocation(x, y);
244 }
245 }
246
247 protected JInternalFrame.JDesktopIcon getIconAt(JDesktopPane desktop,
248 JInternalFrame.JDesktopIcon icon, int x, int y) {
249
250 JInternalFrame.JDesktopIcon currentIcon = null;
251 Component[] components = desktop.getComponents();
252
253 for (int i=0; i<components.length; i++) {
254 Component comp = components[i];
255 if (comp instanceof JInternalFrame.JDesktopIcon &&
256 comp != icon) {
257
258 Point p = comp.getLocation();
259 if (p.x == x && p.y == y) {
260 return (JInternalFrame.JDesktopIcon)comp;
261 }
262 }
263 }
264 return null;
265 }
266 }; /// END of MotifDesktopManager
267}