001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright © 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.graphic.views;
051:
052: import java.awt.Component;
053: import java.awt.Dimension;
054:
055: import javax.swing.JComponent;
056: import javax.swing.JSplitPane;
057: import javax.swing.JViewport;
058:
059: import com.projity.pm.graphic.timescale.ScaledComponent;
060: import com.projity.pm.graphic.views.synchro.ScrollPaneSynchronizer;
061: import com.projity.pm.graphic.views.synchro.Synchronizer;
062: import com.projity.timescale.TimeScaleEvent;
063: import com.projity.timescale.TimeScaleListener;
064: import com.projity.workspace.SavableToWorkspace;
065: import com.projity.workspace.WorkspaceSetting;
066:
067: /**
068: *
069: */
070: public class MainView extends JSplitPane implements TimeScaleListener,
071: SavableToWorkspace {
072: private static final long serialVersionUID = -6427979080094712783L;
073:
074: protected int defaultDividerSize;
075:
076: protected double defaultDividerLocation = 0.7;
077: private Synchronizer synchronizer;
078:
079: /**
080: *
081: */
082: public MainView() {
083: super (JSplitPane.VERTICAL_SPLIT);
084: setOneTouchExpandable(true);
085: defaultDividerSize = getDividerSize();
086: setDividerSize(0);
087:
088: }
089:
090: public void setTop(Component top) {
091: if (top == null)
092: return;
093:
094: Component bottom = getBottomComponent();
095: if (bottom != null) {
096: setDividerSize(defaultDividerSize);
097: setDividerLocation(defaultDividerLocation);
098: }
099: if (top instanceof SplittedView)
100: ((SplittedView) top).setParentView(this );
101: setTopComponent(top);
102:
103: if (viewsSynchronizable()) {
104: if (bottom == null)
105: ((SplittedView) top)
106: .setDividerLocation(((SplittedView) bottom)
107: .getDividerLocation());
108: else
109: ((SplittedView) top)
110: .setDividerLocationSilent(((SplittedView) bottom)
111: .getDividerLocation()
112: + ((SplittedView) bottom)
113: .getDeltaDivider()
114: - ((SplittedView) top)
115: .getDeltaDivider()); //bottom not initialized yet, no sync
116: addScaledComponentsSynchro();
117: }
118: }
119:
120: public void setBottom(Component bottom) {
121: if (bottom == null)
122: return;
123:
124: Component top = getTopComponent();
125: if (top != null) {
126: setDividerSize(defaultDividerSize);
127: setDividerLocation(defaultDividerLocation);
128: }
129: if (bottom instanceof SplittedView)
130: ((SplittedView) bottom).setParentView(this );
131: setBottomComponent(bottom);
132:
133: if (viewsSynchronizable()) {
134: ((SplittedView) bottom)
135: .setDividerLocationSilent(((SplittedView) top)
136: .getDividerLocation()
137: + ((SplittedView) top).getDeltaDivider()
138: - ((SplittedView) bottom).getDeltaDivider()); //bottom not initialized yet, no sync
139: addScaledComponentsSynchro();
140: }
141: }
142:
143: public void removeTop() {
144: removeScaledComponentsSynchro();
145: setTopComponent(null);
146: setDividerSize(0);
147: }
148:
149: public void removeBottom() {
150: removeScaledComponentsSynchro();
151: setBottomComponent(null);
152: setDividerSize(0);
153: }
154:
155: public boolean viewsSynchronizable() {
156: Component top = getTopComponent();
157: Component bottom = getBottomComponent();
158: return (top != null && bottom != null
159: && (top instanceof SplittedView) && (bottom instanceof SplittedView));
160: }
161:
162: public void addScaledComponentsSynchro() {
163: if (viewsSynchronizable()) {
164: SplittedView top = (SplittedView) getTopComponent();
165: SplittedView bottom = (SplittedView) getBottomComponent();
166: JViewport bottomViewport = bottom.rightScrollPane
167: .getViewport();
168: JViewport topViewport = top.rightScrollPane.getViewport();
169: JComponent bottomComponent = (JComponent) bottomViewport
170: .getComponent(0);
171: JComponent topComponent = (JComponent) topViewport
172: .getComponent(0);
173: adjustSizes();
174: ((ScaledComponent) topComponent).getCoord()
175: .addTimeScaleListener(this ); // listener removed in DocumentFrame
176: synchronizer.addSynchro(top.getRightScrollPane(), bottom
177: .getRightScrollPane(),
178: ScrollPaneSynchronizer.VERTICAL, bottom
179: .isNeedVoidBar(), false);
180: }
181: }
182:
183: public void removeScaledComponentsSynchro() {
184: if (viewsSynchronizable()) {
185: SplittedView top = (SplittedView) getTopComponent();
186: SplittedView bottom = (SplittedView) getBottomComponent();
187: // JViewport bottomViewport=bottom.rightScrollPane.getViewport();
188: JViewport topViewport = top.rightScrollPane.getViewport();
189: // JComponent bottomComponent=(JComponent)bottomViewport.getComponent(0);
190: JComponent topComponent = (JComponent) topViewport
191: .getComponent(0);
192: ((ScaledComponent) topComponent).getCoord()
193: .removeTimeScaleListener(this );
194: synchronizer
195: .removeSynchro(top.getRightScrollPane(),
196: bottom == null ? null : bottom
197: .getRightScrollPane(),
198: ScrollPaneSynchronizer.VERTICAL);
199: }
200: }
201:
202: public void setChildrenDividerLocation(Object source, int pos) {
203: SplittedView top = null;
204: SplittedView bottom = null;
205: Component c = getBottomComponent();
206: if (c != null && (c instanceof SplittedView))
207: bottom = (SplittedView) c;
208: c = getTopComponent();
209: if (c != null && (c instanceof SplittedView))
210: top = (SplittedView) c;
211: if (top == null || bottom == null)
212: return;
213: if (bottom.getDeltaDivider() < top.getDeltaDivider()) {
214: SplittedView tmp = bottom;
215: bottom = top;
216: top = tmp;
217: }
218: int delta = bottom.getDeltaDivider() - top.getDeltaDivider();
219:
220: if (source == top && bottom != null) {
221: int min = top.getMinimumDividerLocation();
222: int max = top.getMaximumDividerLocation();
223: if (pos >= max) {
224: top.setDividerLocationSilent(Integer.MAX_VALUE);
225: bottom.setDividerLocationSilent(Integer.MAX_VALUE);
226: } else if (pos <= min + delta) {
227: top.setDividerLocationSilent(1 + delta);
228: bottom.setDividerLocationSilent(1);
229: } else
230: bottom.setDividerLocationSilent(pos - delta);
231: }
232: if (source == bottom && top != null) {
233: int min = bottom.getMinimumDividerLocation();
234: int max = bottom.getMaximumDividerLocation();
235: if (pos >= max - delta) {
236: top.setDividerLocationSilent(Integer.MAX_VALUE);
237: bottom.setDividerLocationSilent(Integer.MAX_VALUE);
238: } else if (pos <= min) {
239: top.setDividerLocationSilent(1 + delta);
240: bottom.setDividerLocationSilent(1);
241: } else
242: top.setDividerLocationSilent(pos + delta);
243: }
244: }
245:
246: public void adjustSizes() {
247: SplittedView top = (SplittedView) getTopComponent();
248: SplittedView bottom = (SplittedView) getBottomComponent();
249: JViewport bottomViewport = bottom.rightScrollPane.getViewport();
250: JViewport topViewport = top.rightScrollPane.getViewport();
251: JComponent bottomComponent = (JComponent) bottomViewport
252: .getView();
253: JComponent topComponent = (JComponent) topViewport.getView();
254:
255: Dimension dtop = topComponent.getPreferredSize();
256: Dimension dbottom = bottomComponent.getPreferredSize();
257: dbottom = new Dimension((int) dtop.getWidth(), (int) dbottom
258: .getHeight());
259: bottomComponent.setPreferredSize(dbottom);
260: }
261:
262: //to be notified when the time window changed
263: public void timeScaleChanged(TimeScaleEvent e) {
264: if (viewsSynchronizable()) {
265: adjustSizes();
266: }
267: }
268:
269: public Synchronizer getSynchronizer() {
270: if (synchronizer == null)
271: synchronizer = new Synchronizer();
272: return synchronizer;
273: }
274:
275: public WorkspaceSetting createWorkspace(int context) {
276: Workspace ws = new Workspace();
277: ws.dividerLocation = getDividerLocation();
278: return ws;
279: }
280:
281: public void restoreWorkspace(WorkspaceSetting w, int context) {
282: Workspace ws = (Workspace) w;
283: setDividerLocation(ws.dividerLocation);
284: }
285:
286: public static class Workspace implements WorkspaceSetting {
287: private static final long serialVersionUID = -8129925562216728220L;
288: int dividerLocation;
289:
290: public int getDividerLocation() {
291: return dividerLocation;
292: }
293:
294: public void setDividerLocation(int dividerLocation) {
295: this.dividerLocation = dividerLocation;
296: }
297: }
298: }
|