001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: ViewTitleBar.java,v 1.24 2007/01/28 21:25:10 jesper Exp $
023: package net.infonode.docking.internal;
024:
025: import net.infonode.docking.View;
026: import net.infonode.docking.internalutil.*;
027: import net.infonode.docking.properties.ViewTitleBarProperties;
028: import net.infonode.docking.properties.ViewTitleBarStateProperties;
029: import net.infonode.gui.ContentTitleBar;
030: import net.infonode.gui.DimensionProvider;
031: import net.infonode.gui.hover.hoverable.HoverManager;
032: import net.infonode.properties.gui.InternalPropertiesUtil;
033: import net.infonode.properties.gui.util.ComponentProperties;
034: import net.infonode.properties.gui.util.ShapedPanelProperties;
035: import net.infonode.properties.propertymap.PropertyMap;
036: import net.infonode.properties.propertymap.PropertyMapListener;
037: import net.infonode.properties.propertymap.PropertyMapTreeListener;
038: import net.infonode.properties.propertymap.PropertyMapWeakListenerManager;
039:
040: import javax.swing.*;
041: import java.awt.*;
042: import java.awt.event.MouseEvent;
043: import java.util.List;
044: import java.util.Map;
045:
046: /**
047: * @author johan
048: */
049: public class ViewTitleBar extends ContentTitleBar {
050: private static final ButtonInfo[] buttonInfos = {
051: new UndockButtonInfo(
052: ViewTitleBarStateProperties.UNDOCK_BUTTON_PROPERTIES),
053: new DockButtonInfo(
054: ViewTitleBarStateProperties.DOCK_BUTTON_PROPERTIES),
055: new MinimizeButtonInfo(
056: ViewTitleBarStateProperties.MINIMIZE_BUTTON_PROPERTIES),
057: new MaximizeButtonInfo(
058: ViewTitleBarStateProperties.MAXIMIZE_BUTTON_PROPERTIES),
059: new RestoreButtonInfo(
060: ViewTitleBarStateProperties.RESTORE_BUTTON_PROPERTIES),
061: new CloseButtonInfo(
062: ViewTitleBarStateProperties.CLOSE_BUTTON_PROPERTIES) };
063:
064: private DimensionProvider minimumSizeProvider;
065: private net.infonode.docking.View view;
066: private AbstractButton[] buttons = new AbstractButton[buttonInfos.length];
067: private List customBarComponents;
068:
069: private PropertyMapTreeListener propertiesListener = new PropertyMapTreeListener() {
070: public void propertyValuesChanged(Map changes) {
071: updateTitleBar(changes);
072: }
073: };
074:
075: private PropertyMapListener buttonsListener = new PropertyMapListener() {
076: public void propertyValuesChanged(PropertyMap propertyMap,
077: Map changes) {
078: updateViewButtons(null);
079: }
080: };
081:
082: public ViewTitleBar(View view) {
083: super (view);
084: this .view = view;
085:
086: PropertyMapWeakListenerManager.addWeakTreeListener(view
087: .getViewProperties().getViewTitleBarProperties()
088: .getMap(), propertiesListener);
089: PropertyMapWeakListenerManager.addWeakListener(view
090: .getWindowProperties().getMap(), buttonsListener);
091:
092: updateTitleBar(null);
093: updateTitle();
094: updateViewButtons(null);
095:
096: HoverManager.getInstance().addHoverable(this );
097: }
098:
099: private void updateTitle() {
100: ViewTitleBarStateProperties titleProps = view
101: .getViewProperties().getViewTitleBarProperties()
102: .getNormalProperties();
103: getLabel().setText(
104: titleProps.getTitleVisible() ? titleProps.getTitle()
105: : null);
106: getLabel().setIcon(
107: titleProps.getIconVisible() ? titleProps.getIcon()
108: : null);
109: }
110:
111: private void updateTitleBar(Map changes) {
112: updateTitle();
113:
114: JLabel label = getLabel();
115: ViewTitleBarProperties titleBarProperties = view
116: .getViewProperties().getViewTitleBarProperties();
117: ShapedPanelProperties shapedProperties = titleBarProperties
118: .getNormalProperties().getShapedPanelProperties();
119: ComponentProperties componentProperties = titleBarProperties
120: .getNormalProperties().getComponentProperties();
121:
122: updateViewButtons(changes);
123:
124: if (changes == null) {
125: minimumSizeProvider = titleBarProperties
126: .getMinimumSizeProvider();
127:
128: componentProperties.applyTo(this );
129:
130: for (int i = 0; i < buttons.length; i++)
131: if (buttons[i] != null) {
132: buttons[i].setForeground(componentProperties
133: .getForegroundColor());
134: buttons[i].setBackground(shapedProperties
135: .getComponentPainter() != null ? null
136: : componentProperties.getBackgroundColor());
137: }
138:
139: {
140: label.setForeground(componentProperties
141: .getForegroundColor());
142: label.setFont(componentProperties.getFont());
143: label.setIconTextGap(titleBarProperties
144: .getNormalProperties().getIconTextGap());
145: }
146:
147: {
148: InternalPropertiesUtil.applyTo(shapedProperties, this );
149: }
150:
151: setLayoutDirection(titleBarProperties.getDirection());
152: setHoverListener(titleBarProperties.getHoverListener());
153: setLabelAlignment(titleBarProperties.getNormalProperties()
154: .getIconTextHorizontalAlignment());
155: } else {
156: // View title bar
157: Map map = (Map) changes.get(titleBarProperties.getMap());
158: if (map != null) {
159: if (map
160: .containsKey(ViewTitleBarProperties.MINIMUM_SIZE_PROVIDER)) {
161: minimumSizeProvider = titleBarProperties
162: .getMinimumSizeProvider();
163: revalidate();
164: }
165:
166: if (map.containsKey(ViewTitleBarProperties.DIRECTION))
167: setLayoutDirection(titleBarProperties
168: .getDirection());
169:
170: if (map
171: .containsKey(ViewTitleBarProperties.HOVER_LISTENER))
172: setHoverListener(titleBarProperties
173: .getHoverListener());
174:
175: }
176:
177: // State properties
178: map = (Map) changes.get(titleBarProperties
179: .getNormalProperties().getMap());
180: if (map != null) {
181: if (map
182: .containsKey(ViewTitleBarStateProperties.ICON_TEXT_GAP))
183: label.setIconTextGap(titleBarProperties
184: .getNormalProperties().getIconTextGap());
185:
186: if (map
187: .containsKey(ViewTitleBarStateProperties.ICON_TEXT_HORIZONTAL_ALIGNMENT))
188: setLabelAlignment(titleBarProperties
189: .getNormalProperties()
190: .getIconTextHorizontalAlignment());
191: }
192:
193: // Component properties
194: map = (Map) changes.get(titleBarProperties
195: .getNormalProperties().getComponentProperties()
196: .getMap());
197: if (map != null) {
198: componentProperties.applyTo(this );
199:
200: label.setForeground(componentProperties
201: .getForegroundColor());
202: label.setFont(componentProperties.getFont());
203:
204: for (int i = 0; i < buttons.length; i++)
205: if (buttons[i] != null) {
206: buttons[i].setForeground(componentProperties
207: .getForegroundColor());
208: buttons[i].setBackground(shapedProperties
209: .getComponentPainter() != null ? null
210: : componentProperties
211: .getBackgroundColor());
212: }
213: }
214:
215: // Shaped panel properties
216: map = (Map) changes.get(titleBarProperties
217: .getNormalProperties().getShapedPanelProperties()
218: .getMap());
219: if (map != null) {
220: InternalPropertiesUtil.applyTo(shapedProperties, this );
221: }
222: }
223: }
224:
225: public void updateViewButtons(Map changes) {
226: InternalDockingUtil.updateButtons(buttonInfos, buttons, null,
227: view, view.getViewProperties()
228: .getViewTitleBarProperties()
229: .getNormalProperties().getMap(), changes);
230:
231: if (shouldUpdateButtons())
232: updateCustomBarComponents(customBarComponents);
233: }
234:
235: private boolean shouldUpdateButtons() {
236: JComponent[] titleComponents = getRightTitleComponents();
237:
238: if (titleComponents == null
239: || titleComponents.length < buttons.length)
240: return true;
241:
242: for (int i = 0; i < buttons.length; i++)
243: if (titleComponents[titleComponents.length - i - 1] != buttons[i])
244: return true;
245:
246: return false;
247: }
248:
249: public void updateCustomBarComponents(List list) {
250: this .customBarComponents = list;
251:
252: int size = list == null ? 0 : list.size();
253: JComponent[] components = new JComponent[size + buttons.length];
254: Insets[] insets = new Insets[components.length];
255:
256: if (list != null) {
257: for (int i = 0; i < list.size(); i++) {
258: components[i] = (JComponent) list.get(i);
259: insets[i] = i == 0 ? new Insets(0, 0, 0, 0)
260: : new Insets(0, view.getViewProperties()
261: .getViewTitleBarProperties()
262: .getNormalProperties()
263: .getButtonSpacing(), 0, 0);
264: }
265: }
266:
267: for (int i = 0; i < buttons.length; i++) {
268: int k = size + i;
269: components[k] = buttons[i];
270: insets[k] = k == 0 ? new Insets(0, 0, 0, 0) : new Insets(0,
271: view.getViewProperties()
272: .getViewTitleBarProperties()
273: .getNormalProperties().getButtonSpacing(),
274: 0, 0);
275: }
276:
277: setRightTitleComponents(components, insets);
278: }
279:
280: public void dispose() {
281: HoverManager.getInstance().removeHoverable(this );
282: }
283:
284: private int pressedCount = 0;
285: private boolean dragOutside = false;
286:
287: protected void processMouseEvent(MouseEvent e) {
288: if (e.getID() == MouseEvent.MOUSE_PRESSED)
289: pressedCount++;
290:
291: if (e.getID() == MouseEvent.MOUSE_RELEASED) {
292: pressedCount--;
293:
294: if (pressedCount <= 0)
295: dragOutside = false;
296: }
297:
298: super .processMouseEvent(e);
299: }
300:
301: protected void processMouseMotionEvent(MouseEvent e) {
302: if (e.getID() == MouseEvent.MOUSE_DRAGGED && !dragOutside) {
303: dragOutside = !contains(e.getPoint());
304: if (!dragOutside)
305: return;
306: }
307:
308: super .processMouseMotionEvent(e);
309: }
310:
311: public Dimension getMinimumSize() {
312: if (minimumSizeProvider == null)
313: return super .getMinimumSize();
314:
315: Dimension d = minimumSizeProvider.getDimension(this );
316: return d == null ? super .getMinimumSize() : d;
317: }
318:
319: public Dimension getPreferredSize() {
320: Dimension d = minimumSizeProvider == null ? null
321: : minimumSizeProvider.getDimension(this );
322:
323: Dimension pSize = super .getPreferredSize();
324: if (d == null)
325: return pSize;
326:
327: return new Dimension(Math.max(d.width, pSize.width), Math.max(
328: d.height, pSize.height));
329: }
330: }
|