/* * Copyright 2011 Mark McKay * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package automenta.vivisect.swing.dock; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Point; import java.awt.Rectangle; import java.util.ArrayList; import java.util.EventObject; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JSplitPane; import static javax.swing.SwingUtilities.getWindowAncestor; /** * * @author kitfox */ public class DockingRegionContainer extends JPanel implements DockingContainer { private DockingChild root; JPanel panel_minimizeBar; final JPanel panel_workArea; final ArrayList<MinMaxRecord> minimizedRecords = new ArrayList<>(); MinMaxRecord maximizedRecord; private final DockingRegionRoot dockRoot; JComponent oldGlass; final DraggingOverlayPanel overlayPanel; public DockingRegionContainer(final DockingRegionRoot dockRoot) { this.dockRoot = dockRoot; setLayout(new BorderLayout()); panel_workArea = new JPanel(); panel_workArea.setLayout(new BorderLayout()); add(panel_workArea, BorderLayout.CENTER); overlayPanel = new DraggingOverlayPanel(this); overlayPanel.setVisible(true); root = new DockingRegionTabbed(); root.setDockParent(this); panel_workArea.add(root.getComponent()); } public void addDockingRegionContainerListener(DockingRegionContainerListener l) { //listeners.add(l); listenerList.add(DockingRegionContainerListener.class, l); } public void removeDockingRegionContainerListener(DockingRegionContainerListener l) { // listeners.remove(l); listenerList.remove(DockingRegionContainerListener.class, l); } @Override public DockingRegionSplit split(DockingChild child, DockingContent content, boolean right, boolean vertical) { if (child != root) { //We should always be updating the old child throw new IllegalArgumentException(); } DockingRegionTabbed newRegion = new DockingRegionTabbed(); newRegion.addTab(content); DockingChild leftChild, rightChild; leftChild = right ? root : newRegion; rightChild = right ? newRegion : root; DockingRegionSplit split = new DockingRegionSplit(leftChild, rightChild); split.setDockParent(this); split.setOrientation(vertical ? JSplitPane.VERTICAL_SPLIT : JSplitPane.HORIZONTAL_SPLIT); root = split; panel_workArea.removeAll(); panel_workArea.add(split, BorderLayout.CENTER); revalidate(); return split; } @Override public void join(DockingChild oldChild, DockingChild newChild) { if (oldChild != root) { //We should always be updating the old child throw new IllegalArgumentException(); } if (newChild == null) { fireDockingContainerEmpty(); return; } root = newChild; newChild.setDockParent(this); panel_workArea.removeAll(); panel_workArea.add(root.getComponent(), BorderLayout.CENTER); revalidate(); } protected void fireDockingContainerEmpty() { EventObject evt = new EventObject(this); for (DockingRegionContainerListener l : listenerList.getListeners(DockingRegionContainerListener.class)) { l.dockingContainerEmpty(evt); } } /** * @return the root */ public DockingChild getRoot() { return root; } public void setRoot(DockingChild root) { this.root = root; this.root.setDockParent(this); // panel_workArea.removeAll(); // panel_workArea.add(root.getComponent(), BorderLayout.CENTER); minimizedRecords.clear(); maximizedRecord = null; rebuildMinimizeBar(); rebuildWorkArea(); revalidate(); } // @Override // public int getNumDockChildren() // { // return 1; // } // // @Override // public DockingChild getDockChild(int index) // { // if (index != 1) // { // throw new IllegalArgumentException(); // } // // return root; // } public void addDockContent(DockingContent content) { root.addDockContent(content); } @Override public DockingPathRecord buildPath(DockingChild dockChild, DockingPathRecord childPath) { return childPath; } @Override public DockingRegionContainer getContainerRoot() { return this; } public void floatWindow(DockingContent content, DockingPathRecord partialPath) { // DockingRegionTabbed tab = (DockingRegionTabbed)partialPath.getLast().getDockingChild(); DockingRegionTabbed tab = (DockingRegionTabbed) root.getDockingChild(partialPath); tab.removeTab(content); DockingRegionWindow win = dockRoot.createFloatingWindow(); win.getRoot().addDockContent(content); win.pack(); centerWindow(win, getWindowAncestor(dockRoot).getBounds()); } public void maximize(DockingContent content, DockingPathRecord partialPath) { if (maximizedRecord != null) { throw new IllegalArgumentException(); } // DockingRegionTabbed tab = (DockingRegionTabbed)partialPath.getLast().getDockingChild(); DockingRegionTabbed tab = (DockingRegionTabbed) root.getDockingChild(partialPath); tab.removeTab(content); maximizedRecord = new MinMaxRecord(content, partialPath); rebuildWorkArea(); rebuildMinimizeBar(); } void restoreFromMaximize(DockingContent content) { if (maximizedRecord.getContent() != content) { throw new IllegalArgumentException(); } DockingRegionTabbed tab = (DockingRegionTabbed) root.getDockingChild(maximizedRecord.path); tab.restore(content, maximizedRecord.path.getLast()); // maximizedRecord.path.getDockingChild().restore( // maximizedRecord.getContent(), maximizedRecord.getPath()); maximizedRecord = null; rebuildWorkArea(); rebuildMinimizeBar(); } void closeFromMaximize(DockingContent content) { if (maximizedRecord.getContent() != content) { throw new IllegalArgumentException(); } maximizedRecord = null; rebuildWorkArea(); rebuildMinimizeBar(); } void floatFromMaximize(DockingContent content) { if (maximizedRecord.getContent() != content) { throw new IllegalArgumentException(); } maximizedRecord = null; rebuildWorkArea(); rebuildMinimizeBar(); DockingRegionWindow win = dockRoot.createFloatingWindow(); win.getRoot().addDockContent(content); win.pack(); centerWindow(win, getWindowAncestor(dockRoot).getBounds()); } public void minimize(DockingContent content, DockingPathRecord partialPath) { DockingRegionTabbed tab = (DockingRegionTabbed) root.getDockingChild(partialPath); // DockingRegionTabbed tab = (DockingRegionTabbed)partialPath.getLast().getDockingChild(); tab.removeTab(content); MinMaxRecord rec = new MinMaxRecord(content, partialPath); minimizedRecords.add(rec); rebuildMinimizeBar(); } void closeMinimized(MinMaxRecord record) { minimizedRecords.remove(record); rebuildMinimizeBar(); } void restoreMinimized(MinMaxRecord record) { minimizedRecords.remove(record); rebuildMinimizeBar(); // record.path.getDockingChild().restore( // record.getContent(), record.getPath()); DockingRegionTabbed tab = (DockingRegionTabbed) root.getDockingChild(record.getPath()); tab.restore(record.getContent(), record.getPath().getLast()); } private void rebuildMinimizeBar() { if (minimizedRecords.isEmpty() || maximizedRecord != null) { if (panel_minimizeBar != null) { remove(panel_minimizeBar); panel_minimizeBar = null; } } else { if (panel_minimizeBar == null) { panel_minimizeBar = new JPanel(); add(panel_minimizeBar, BorderLayout.SOUTH); FlowLayout layout = new FlowLayout(FlowLayout.LEFT); panel_minimizeBar.setLayout(layout); } panel_minimizeBar.removeAll(); for (MinMaxRecord rec : minimizedRecords) { MinimizeTitlePanel button = new MinimizeTitlePanel(rec); panel_minimizeBar.add(button); } } revalidate(); repaint(); } private void rebuildWorkArea() { panel_workArea.removeAll(); if (maximizedRecord == null) { panel_workArea.add(root.getComponent(), BorderLayout.CENTER); } else { DockingRegionMaximized panel = new DockingRegionMaximized(maximizedRecord); panel_workArea.add(panel, BorderLayout.CENTER); } revalidate(); repaint(); } private void centerWindow(DockingRegionWindow win, Rectangle bounds) { int dw = (bounds.width - win.getWidth()) / 2; int dh = (bounds.height - win.getHeight()) / 2; win.setLocation(bounds.x + dw, bounds.y + dh); } /** * @return the dockRoot */ public DockingRegionRoot getDockRoot() { return dockRoot; } void showDragControl() { //System.err.println("showDragControl()"); JRootPane rootPane = getRootPane(); oldGlass = (JComponent) rootPane.getGlassPane(); // overlayPanel = new DraggingOverlayPanel(this); rootPane.setGlassPane(overlayPanel); overlayPanel.setVisible(true); rootPane.revalidate(); rootPane.repaint(); } void hideDragControl() { //System.err.println("hideDragControl()"); JRootPane rootPane = getRootPane(); rootPane.setGlassPane(oldGlass); oldGlass = null; // overlayPanel = null; rootPane.revalidate(); rootPane.repaint(); } void clearAllOverlays() { dockRoot.clearAllOverlays(); } void clearOverlay() { overlayPanel.clearOverlay(); } public DockingPickRecord pickContainer(Point containerPoint) { return root.pickContainer(containerPoint); } public DockingChild getDockingChild(DockingPathRecord path) { return root.getDockingChild(path); } public void closeAll() { minimizedRecords.clear(); maximizedRecord = null; root.closeAll(); } //--------------------------------- public class MinMaxRecord { private final DockingContent content; private final DockingPathRecord path; public MinMaxRecord(DockingContent content, DockingPathRecord path) { this.content = content; this.path = path; } /** * @return the content */ public DockingContent getContent() { return content; } /** * @return the path */ public DockingPathRecord getPath() { return path; } public DockingRegionContainer getContainer() { return DockingRegionContainer.this; } } }