diff --git a/Source/mesquite/cartographer/BasicTaxaWindowMaker/BasicTaxaWindowMaker.java b/Source/mesquite/cartographer/BasicTaxaWindowMaker/BasicTaxaWindowMaker.java index ac95db4..6b76906 100644 --- a/Source/mesquite/cartographer/BasicTaxaWindowMaker/BasicTaxaWindowMaker.java +++ b/Source/mesquite/cartographer/BasicTaxaWindowMaker/BasicTaxaWindowMaker.java @@ -1 +1 @@ -/* Mesquite.cartographer source code. Copyright 2008-2009 D. Maddison and W. Maddison. Version 1.3, June 2008. Disclaimer: The Mesquite source code is lengthy and we are few. There are no doubt inefficiencies and goofs in this code. The commenting leaves much to be desired. Please approach this source code with the spirit of helping out. Perhaps with your help we can be more than a few, and make Mesquite better. Mesquite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Mesquite's web site is http://mesquiteproject.org This source code and its compiled class files are free and modifiable under the terms of GNU Lesser General Public License. (http://www.gnu.org/copyleft/lesser.html) */ package mesquite.cartographer.BasicTaxaWindowMaker; /*~~ */ import java.util.*; import java.awt.*; import java.awt.event.*; import mesquite.lib.*; import mesquite.lib.duties.*; /** Makes and manages a Taxa Window for taxa editing and visualization */ public class BasicTaxaWindowMaker extends TaxaWindowMaker implements CommandableOwner, TaxaDisplayActive { public DrawTaxaCoordinator taxaDrawCoordTask; // public TaxaSource taxaSourceTask; public Vector contextListeners; Taxa taxa; static boolean warnUnsaved; BasicTaxaWindow basicTaxaWindow; // MesquiteString taxaSourceName; // MesquiteCommand tsC; static { warnUnsaved = true; } /*...................................................................................................................*/ public boolean startJob(String arguments, Object condition, boolean hiredByName) { loadPreferences(); makeMenu("Taxa"); /* taxaSourceTask= (TaxaSource)hireCompatibleEmployee(TaxaSource.class, condition, "Source of taxa (Taxa window)"); if (taxaSourceTask == null) return sorry(getName() + " couldn't start because no source of taxa was obtained."); taxaSourceName = new MesquiteString(taxaSourceTask.getName()); tsC = makeCommand("setTaxaSource", this); taxaSourceTask.setHiringCommand(tsC); defineMenus(false); */ if (MesquiteThread.isScripting() && getProject().developing) respondToWindowResize = false; // this prevents a lot of tree/window resizing when file being re-read contextListeners = new Vector(); //setAutoSaveMacros(true); return true; } boolean respondToWindowResize = true; public void fileReadIn(MesquiteFile f) { respondToWindowResize = true; if (basicTaxaWindow != null) { basicTaxaWindow.fileReadIn(); } } /*--------------------------------------*/ public boolean isPrerelease(){ return false; } // public String getExpectedPath(){ // return getPath() + "recent"; // } /*--------------------------------------*/ /*Menus defined in this method are visible to Mesquite's automatic documentation system (overrides method of MesquiteModule)* public void defineMenus(boolean accumulating){ if (accumulating || numModulesAvailable(TaxaSource.class)>1) { MesquiteSubmenuSpec mss = addSubmenu(null, "Taxa Source", tsC); if (!accumulating){ mss.setSelected(taxaSourceName); mss.setList(TaxaSource.class); if (taxa !=null) mss.setCompatibilityCheck(taxa); } } } /*--------------------------------------*/ public Commandable[] getCommandablesForAccumulation(){ Commandable[] cs = new Commandable[1]; cs[0]= new BasicTaxaWindow(); return cs; } public void employeeQuit(MesquiteModule m){ if (basicTaxaWindow!=null) basicTaxaWindow.contentsChanged(); } public void processPreferencesFromFile (String[] prefs) { if (prefs!=null && prefs.length>0) { if (prefs[0].equals("warned")) { warnUnsaved = false; } } } /*.................................................................................................................*/ public String preparePreferencesForXML () { StringBuffer buffer = new StringBuffer(); StringUtil.appendXMLTag(buffer, 2, "warnUnsaved", warnUnsaved); return buffer.toString(); } /*.................................................................................................................*/ public void processSingleXMLPreference (String tag, String content) { if ("warnUnsaved".equalsIgnoreCase(tag)) warnUnsaved = MesquiteBoolean.fromTrueFalseString(content); } /*.................................................................................................................*/ public Snapshot getSnapshot(MesquiteFile file) { if (basicTaxaWindow==null) return null; Snapshot temp = new Snapshot(); Snapshot fromWindow = basicTaxaWindow.getSnapshot(file); // temp.addLine("setTaxaSource " , taxaSourceTask); temp.addLine("setAssignedID " + getPermanentIDString()); //for taxa context temp.addLine("getTaxaWindow"); temp.addLine("tell It"); temp.incorporate(fromWindow, true); for (int i = 0; i2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 Shape c = g.getClip(); g.setClip(0, 0, 99999, 99999); if (basicTaxaWindow.isFauxScrollPane()) g.setClip(basicTaxaWindow.getTaxaViewport()); boolean st = basicTaxaWindow.ScanTouch(g, x, y, modifiers); g.setClip(c); return st; } /*.................................................................................................................*/ public boolean mouseUpInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanDrop( g, x, y, modifiers); return true; } /*.................................................................................................................*/ public boolean mouseMoveInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanFlash(g, x, y, modifiers); //basicTaxaWindow.setExplanation(basicTaxaWindow.baseExplanation, false); return true; } /*.................................................................................................................*/ public boolean mouseDragInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanDrag(g, x, y, modifiers); return true; } /*.................................................................................................................*/ /**Returns command to hire employee if clonable*/ public String getClonableEmployeeCommand(MesquiteModule employee){ if (employee!=null && employee.getEmployer()==this) { if (employee.getHiredAs()==TaxaWindowAssistant.class) return ("newWindowAssistant " + StringUtil.tokenize(employee.getName()) + ";");//quote if (employee.getHiredAs()==TaxaDisplayAssistant.class) return ("newAssistant " + StringUtil.tokenize(employee.getName()) + ";");//quote } return null; } } /* ======================================================================== */ class BasicTaxaWindow extends MesquiteWindow implements Fittable, MesquiteListener, AdjustmentListener { TaxaDisplay taxaDisplay; boolean properlyFormed = false; Taxa taxa; DrawTaxaCoordinator taxaDrawCoordTask; boolean taxaEdited=false; TaxaScrollPane taxaPane; Adjustable hScroll, vScroll; boolean usingPane = false; boolean scaleToFit = false; // TaxaSource taxaSourceTask; boolean warningGivenForTaxaSource = false; static final int scrollWidth = 16; static final int initalWindowHeight = 400; static final int initalWindowWidth = 520; static final int baseMessageWidth = 256; int messageWidth = 256; int totalTaxaFieldWidth = 800; int totalTaxaFieldHeight = 800; MessagePanel messagePanel; boolean canUndo = true; TaxaTool currentTaxaTool; MesquiteBoolean floatLegends; BasicTaxaWindowMaker windowModule; int highlightedTaxa=-1; int xFrom, yFrom, xTo, yTo; boolean usingDefaultBush = false; //MesquiteMenuItemSpec sizeItem; static int numWindows=0; private int windowNum=0; int initPosX = 0; int initPosY = 0; // long treeVersion = 0; MesquiteString baseExplanation; boolean baseExplanationUsed=false; // boolean treeAnnotationShown = false; MesquiteMenuItemSpec floatLegendsItem; int oldH = 0; int oldV = 0; boolean showTaxaListOnSave = false; //have preference for this? Dimension oldPreferred = null; /*When lockStoredTrees is true (MacClade mode), editing a stored tree causes the tree to be treated as unsaved, and for the new tree to be saved, Store Tree or Replace Stored Tree must be called. When false, editing a stored tree changes the original in storage.*/ //boolean lockStoredTrees = false; //LockPanel lockPanel; public BasicTaxaWindow(){ } public BasicTaxaWindow ( BasicTaxaWindowMaker ownerModule, Taxa taxa){ super(ownerModule, true); //INFOBAR setWindowSize(initalWindowWidth,initalWindowHeight); ownerModule.setModuleWindow(this); baseExplanation = new MesquiteString(""); numWindows++; windowNum=numWindows; windowModule = ownerModule; this.taxa=taxa; TaxaTool tool1 = new TaxaTool(this, "arrow", MesquiteModule.getRootImageDirectoryPath(), "arrow.gif", 4,2,"Arrow Tool", "This is the standard arrow tool."); tool1.setTouchedCommand(MesquiteModule.makeCommand("touchTaxa", this)); currentTaxaTool = tool1; addTool(tool1); setCurrentTool(currentTaxaTool); currentTaxaTool.setInUse(true); currentTaxaTool.setIsArrowTool(true); taxaDrawCoordTask= windowModule.hireTaxaDrawCoordTask(); if (taxaDrawCoordTask==null) return; this.ownerModule = ownerModule; // this.taxaSourceTask=tsT; floatLegends = new MesquiteBoolean(true); if (taxa!=null) { taxa.addListener(this); } taxaDisplay =taxaDrawCoordTask.createOneTaxaDisplay(taxa, this); taxaDisplay.setLocation(0, 0); ownerModule.addModuleMenuItems(null, ownerModule.makeCommand("newWindowAssistant", this), TaxaWindowAssistantN.class); ownerModule.addModuleMenuItems(null, ownerModule.makeCommand("newAssistant", this), TaxaDisplayAssistantD.class); // ownerModule.addMenuItem( "-", null); MesquiteSubmenuSpec mBringToFrontAsst = ownerModule.addSubmenu(null, "Bring To Front"); mBringToFrontAsst.setList(taxaDisplay.getExtras()); mBringToFrontAsst.setListableFilter(TaxaDisplayDrawnExtra.class); mBringToFrontAsst.setCommand(ownerModule.makeCommand("bringToFront", this)); MesquiteSubmenuSpec mSaveMacroAsst = ownerModule.addSubmenu(null, "Save Taxa Analysis as Macro"); mSaveMacroAsst.setList(ownerModule.getEmployeeVector()); mSaveMacroAsst.setListableFilter(TaxaDisplayAssistantAD.class); mSaveMacroAsst.setCommand(ownerModule.makeCommand("saveMacroDisplayAssistant", this)); MesquiteSubmenuSpec mCloseAsst = ownerModule.addSubmenu(null, "Close/Remove"); mCloseAsst.setList(ownerModule.getEmployeeVector()); mCloseAsst.setListableFilter(TaxaDisplayAssistantAD.class); mCloseAsst.setCommand(ownerModule.makeCommand("closeDisplayAssistant", this)); taxaDrawCoordTask.addMenuItem("-", null); //taxaDrawCoordTask.addCheckMenuItem(null, "Use Suggested Size", ownerModule.makeCommand("useSuggestedSize", this), useSuggestedSize); // taxaDrawCoordTask.addCheckMenuItem(null, "Size To Window", ownerModule.makeCommand("toggleSizeToFit", this), sizeToFit); // sizeItem = taxaDrawCoordTask.addMenuItem("Drawing Size...", MesquiteModule.makeCommand("sizeDrawing", this)); floatLegendsItem = taxaDrawCoordTask.addCheckMenuItem(null, "Float Legends", ownerModule.makeCommand("toggleLegendFloat", this), floatLegends); taxaDisplay.setTaxa(taxa); taxaDisplay.setTaxonNameBuffer(30); messagePanel=new MessagePanel(ownerModule); addToWindow(messagePanel); messagePanel.setVisible(true); /* lockPanel=new LockPanel(this); addToWindow(lockPanel); lockPanel.setLocation(0, getHeight()-scrollWidth); lockPanel.setVisible(true); */ //setBackground(Color.white); setBackground(ColorTheme.getInterfaceElement()); messagePanel.setLocation(0, getHeight()-scrollWidth); //togglePane(true, true); taxaPane = new TaxaScrollPane(this); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); hScroll.addAdjustmentListener(this); vScroll.addAdjustmentListener(this); taxaDisplay.setVisible(true); ownerModule.hireAllEmployees(TaxaWindowAssistantI.class); Enumeration em = ownerModule.getEmployeeVector().elements(); while (em.hasMoreElements()) { Object obj = em.nextElement(); MesquiteModule mb = (MesquiteModule)obj; if (mb instanceof TaxaWindowAssistant) { ((TaxaWindowAssistant)mb).setTaxa(taxa); } } setShowExplanation(true); setShowAnnotation(true); baseExplanation.setValue("This is a taxa window. In it you can view taxa from various taxa sources."); setExplanation(baseExplanation, true); // taxaWindowTask.doCommand("makeTaxaWindow", getProject().getTaxaReferenceInternal(taxa), checker); sizeDisplay(); resetTitle(); doCommand("useSuggestedSize",null, CommandChecker.defaultChecker); properlyFormed = true; } /*.................................................................................................................*/ public boolean getProperlyFormed(){ return properlyFormed; } /*.................................................................................................................*/ /** When called the window will determine its own title. MesquiteWindows need to be self-titling so that when things change (names of files, tree blocks, etc.) they can reset their titles properly*/ public void resetTitle(){ String t; t = "Taxa Window " + windowNum + " for taxa \"" +taxa.getName() + "\""; //else // t = "Taxa Window " + windowNum + " showing " + taxaSourceTask.getNameForMenuItem(); setTitle(t); } private void toggleLegendFloat(){ if (taxaPane == null || floatLegends.getValue()) { //legends can't float checkLegendPositionsLegal(); } else { //undoing floating //get bounds on visible part of taxaDisplay Point pt = taxaPane.getScrollPosition(); Dimension dim = taxaPane.getViewportSize(); //cycle through all components getting those that are Legends Component[] cc = taxaDisplay.getComponents(); if (cc!=null && cc.length>0) for (int i=0; i dim.width /2) { //move legend to right border legend.setOffsetX(taxaDisplay.getBounds().width - dim.width + legend.getOffsetX()); done = true; } else { //move legend to left border legend.setOffsetX(legend.getOffsetX() - pt.x); done = true; } if (rect.y - pt.y > dim.height/2){ //move legend to bottom border legend.setOffsetY(taxaDisplay.getBounds().height - dim.height + legend.getOffsetY()); done = true; } else { //move legend to left border legend.setOffsetY(legend.getOffsetY() - pt.y); done = true; } if (done) legend.adjustLocation(); } } checkLegendPositionsLegal(); } } void checkLegendPositionsLegal(){ if (taxaDisplay == null) return; try { if (taxaPane == null || !floatLegends.getValue()) { //legends can't float or aren't floating Component[] cc = taxaDisplay.getComponents(); if (cc!=null && cc.length>0) for (int i=0; i0) for (int i=0; i pt.x+dim.width) { //move legend left amountX = - rect.x - rect.width + (pt.x+dim.width); } else if (rect.x pt.y+dim.height){ //move legend up amountY = -rect.y - rect.height + ( pt.y+dim.height); } else if (rect.y0) for (int i=0; i0) for (int i=0; i 0) for (int i = 0; i < cc.length; i++) { if (cc[i] instanceof Legend) { Legend legend = (Legend) cc[i]; legend.setOffsetX(legend.getOffsetX() + changeH); legend.setOffsetY(legend.getOffsetY() + changeV); legend.adjustLocation(); } } } oldH = hScroll.getValue(); oldV = vScroll.getValue(); } else checkPanelPositionsLegal(); } /*.................................................................................................................*/ boolean isFauxScrollPane() { if (usingPane) return taxaPane.isFauxScrollPane(); return false; } Rectangle getTaxaViewport() { if (usingPane && hScroll != null) { if (!isFauxScrollPane() && MesquiteTrunk.isMacOSX()) return new Rectangle(0, 0, taxaDisplay.getWidth(), taxaDisplay.getHeight()); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); return new Rectangle(hScroll.getValue(), vScroll.getValue(), taxaPane.getContentsWidth(), taxaPane.getContentsHeight()); // SCROLLPANEreturn taxaPane.getViewportSize(); } else return new Rectangle(0, 0, taxaDisplay.getWidth(), taxaDisplay.getHeight()); } Dimension getTaxaViewportSize() { if (usingPane) return taxaPane.getViewportSize(); // SCROLLPANEreturn taxaPane.getViewportSize(); else return new Dimension(taxaDisplay.getWidth(), taxaDisplay.getHeight()); } Point getTaxaScrollPoint() { if (usingPane) return taxaPane.getScrollPosition(); // SCROLLPANEreturn taxaPane.getScrollPosition(); else return new Point(0, 0); } int getTaxaPaneWidth() { if (usingPane) return taxaPane.getBounds().width; else return taxaDisplay.getBounds().width; } int getTaxaPaneHeight() { if (usingPane) return taxaPane.getBounds().height; else return taxaDisplay.getBounds().height; } /* ................................................................................................................. */ public void togglePane(boolean paneOn, boolean resetOrigin) { if (paneOn) { if (!usingPane) { messageWidth = baseMessageWidth; removeFromWindow(taxaDisplay); addToWindow(taxaPane); taxaPane.setLocation(0, 0); taxaPane.addTaxaDisplay(taxaDisplay); usingPane = true; taxaPane.setSize(getWidth(), getHeight() - scrollWidth); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); hScroll.setUnitIncrement(10); hScroll.setBlockIncrement((getWidth() - scrollWidth) / 10); /* * hScroll.setBounds(0, getHeight()-scrollWidth-scrollWidth, getWidth()-scrollWidth, scrollWidth); vScroll.setBounds(getWidth()-scrollWidth, 0, scrollWidth, getHeight()-scrollWidth-scrollWidth); */ vScroll.setBlockIncrement((getHeight() - scrollWidth) / 10); vScroll.setUnitIncrement(10); resetScrolls(); oldH = hScroll.getValue(); oldV = vScroll.getValue(); floatLegendsItem.setEnabled(true); // if (!initiating) { ownerModule.resetContainingMenuBar(); // taxaPane.setVisible(true); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); // lockPanel.repaint(); // } setOrigin(0, 0, true); // initiating = false; taxaPane.doLayout(); } } else { if (usingPane) { usingPane = false; removeFromWindow(taxaPane); addToWindow(taxaDisplay); if (floatLegendsItem != null) floatLegendsItem.setEnabled(false); // if (!initiating) { taxaPane.setSize(getWidth(), getHeight() - scrollWidth); ownerModule.resetContainingMenuBar(); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); taxaDisplay.setLocation(0, 0); /* End new code added Feb.07 oliver */ // lockPanel.repaint(); // } // initiating = false; } if (resetOrigin) setOrigin(0, 0, true); } taxaDisplay.setVisRect(getTaxaViewport()); } public void setOrigin(int x, int y, boolean setScrolls) { if (x < 0) x = 0; if (y < 0) y = 0; if (usingPane) { taxaDisplay.setLocation(-x, -y); if (setScrolls) { hScroll.setValue(x); vScroll.setValue(y); } taxaDisplay.setVisRect(getTaxaViewport()); } resetLegends(); } public void resetScrolls() { if (hScroll.getValue() < 0) hScroll.setValue(0); if (vScroll.getValue() < 0) { vScroll.setValue(0); } } /*.................................................................................................................* public void togglePane(boolean initiating) { togglePane(initiating, true); } /*.................................................................................................................* public void togglePane(boolean initiating, boolean resetOrigin) { if (taxaPane==null || initiating) { if (!initiating) removeFromWindow(taxaDisplay); messageWidth=baseMessageWidth; taxaPane = new TaxaScrollPane(this); taxaPane.setLocation(0, 0); hAdjust = taxaPane.getHAdjustable(); hAdjust.addAdjustmentListener(this); vAdjust = taxaPane.getVAdjustable(); vAdjust.addAdjustmentListener(this); oldH = hAdjust.getValue(); oldV = vAdjust.getValue(); taxaPane.addTaxaDisplay(taxaDisplay); addToWindow(taxaPane); sizeDisplay(resetOrigin); //taxaPane.setScrollPosition(-initPosX, -initPosY); floatLegendsItem.setEnabled(true); if (!initiating) { ownerModule.resetContainingMenuBar(); taxaPane.setVisible(true); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); } } if (resetOrigin) setOrigin(0, 0, true); } /*.................................................................................................................*/ /** Called in some circumstances (not all) when a component is added to a container in the window. Currently used so that the taxa window knows that a component has been added to the TaxaDisplay.*/ public void componentAdded(Container cont, Component comp){ checkLegendPositionsLegal(); } /*.................................................................................................................*/ public void sizeDisplay(){ if (taxaPane!=null){ //Debugg.printStackTrace("\nstart of sizeDisplay " + taxaPane.getScrollPosition()); } if (taxaDisplay==null ||messagePanel==null) return; scaleToFit = taxaDisplay.getScaleToFit(); if (scaleToFit) { togglePane(true, true); if (taxaPane != null) taxaPane.setSize(getWidth(), getHeight() - scrollWidth); int width = getWidth(); int height = getHeight()-scrollWidth; Dimension d = taxaDrawCoordTask.getPreferredSize(); if (d.getHeight()>0) { double mapRatio = d.getWidth()/d.getHeight(); double currentRatio = 1.0*width/height; double shrink = 1.0; if (mapRatio>currentRatio) { // then the map is relatively wider than the current window, so need to shrink to fit width int newHeight = (int)(height*(currentRatio/mapRatio)); taxaDisplay.setSize(width, newHeight); taxaDisplay.setFieldSize(width, newHeight); } else { int newWidth = (int)(width*(mapRatio/currentRatio)); taxaDisplay.setSize(newWidth, height); taxaDisplay.setFieldSize(newWidth, height); } } // taxaDrawCoordTask.get taxaDisplay.redoCalculations(8813); //togglePane(true, false); } else { // not scale to fit Dimension s = taxaDrawCoordTask.getPreferredSize(); oldPreferred = s; if (s != null) { //if taxadrawer has preferred size then put here totalTaxaFieldWidth = s.width; totalTaxaFieldHeight = s.height; toggleLegendFloat(); } else if (taxa.getNumTaxa()>50) { totalTaxaFieldWidth = taxa.getNumTaxa()*14; totalTaxaFieldHeight = taxa.getNumTaxa()*14; toggleLegendFloat(); } togglePane(true, false); if (taxaPane != null) taxaPane.setSize(getWidth(), getHeight() - scrollWidth); taxaDisplay.setFieldSize(totalTaxaFieldWidth, totalTaxaFieldHeight); int useWidth = MesquiteInteger.maximum(totalTaxaFieldWidth, getWidth()); int useHeight = MesquiteInteger.maximum(totalTaxaFieldHeight, getHeight()-scrollWidth); taxaDisplay.setSize(useWidth,useHeight); } if (usingPane) { // taxaDisplay.setSize(getWidth()-scrollWidth, getHeight()-scrollWidth-scrollWidth); // hScroll.setBounds(0, getHeight()-scrollWidth-scrollWidth+1, getWidth()-scrollWidth, scrollWidth); // vScroll.setBounds(getWidth()-scrollWidth, 0, scrollWidth, getHeight()-scrollWidth-scrollWidth); // hScroll.setValue(taxaPane.x); //Debugg.println(" taxaDisplay.getFieldWidth(): " + taxaDisplay.getFieldWidth() + ", taxaPane.getWidth()" + taxaPane.getWidth()); taxaPane.setHMinMax(0, taxaDisplay.getFieldWidth() - taxaPane.getWidth() - scrollWidth); int increment = taxaPane.getHeight() / 10; if (increment>taxaDisplay.getFieldHeight()) increment = taxaDisplay.getFieldHeight(); vScroll.setBlockIncrement(increment); increment = taxaPane.getWidth() / 10; if (increment>taxaDisplay.getFieldWidth()) increment = taxaDisplay.getFieldWidth(); hScroll.setBlockIncrement(increment); vScroll.setUnitIncrement(10); hScroll.setUnitIncrement(10); resetScrolls(); taxaPane.setVMinMax(0, taxaDisplay.getFieldHeight() - taxaPane.getHeight() - scrollWidth - scrollWidth); taxaPane.doLayout(); // vScroll.doLayout(); // hScroll.doLayout(); // setOrigin(treeRect.x, treeRect.y); } else { taxaDisplay.setSize(getWidth(), getHeight() - scrollWidth); setOrigin(0, 0, true); } taxaDisplay.setVisRect(getTaxaViewport()); /* if (taxaPane!=null){ hScroll = taxaPane.getHAdjustable(); vScroll= taxaPane.getVAdjustable(); int oldH = hScroll.getValue(); int oldV = vScroll.getValue(); taxaPane.setSize(getWidth(),getHeight()-scrollWidth); taxaPane.setVisible(true); taxaPane.doLayout(); setOrigin(oldH, oldV, true);// here it is } */ messageWidth = getWidth(); messagePanel.setLocation(0, getHeight()-scrollWidth); messagePanel.setSize(messageWidth,scrollWidth); checkLegendPositionsLegal(); } /*.................................................................................................................* void setSuggestedSize(boolean setToDefault, boolean togglepane){ Dimension s = taxaDrawCoordTask.getPreferredSize(); oldPreferred = s; if (!setToDefault && s != null) { //if taxadrawer has perferred size then put here totalTaxaFieldWidth = s.width; totalTaxaFieldHeight = s.height; toggleLegendFloat(); } else if (taxa.getNumTaxa()>50) { totalTaxaFieldWidth = taxa.getNumTaxa()*14; totalTaxaFieldHeight = taxa.getNumTaxa()*14; toggleLegendFloat(); } if (togglepane) togglePane(false); sizeDisplay(); } /*.................................................................................................................*/ public Taxa getTaxa() { return taxa; } /*.................................................................................................................*/ public void hideTaxa() { if (taxaDisplay!=null) taxaDisplay.setVisible(false); } /*.................................................................................................................*/ public void showTaxa() { if (taxaDisplay!=null) taxaDisplay.setVisible(true); } /*.................................................................................................................* public void setTaxaSource(TaxaSource tsTask) { boolean setToZero = tsTask != taxaSourceTask; taxaSourceTask = tsTask; resetTitle(); if (!MesquiteThread.isScripting()){ resetForTaxaSource(setToZero, true); contentsChanged(); taxaDisplay.repaint(); } else { resetForTaxaSource(setToZero, true); } } /*.................................................................................................................* public void resetForTaxaSource(boolean setToZero, boolean firstTimeTaxaSource) { if (firstTimeTaxaSource) warningGivenForTaxaSource = false; MesquiteTree editedTree = null; if (taxa !=null && taxa.isDoomed()) { ownerModule.iQuit(); return; } treeAnnotationShown = false; taxaDisplay.setTaxa(null); //done to catch spurious redraws checkLegendPositionsLegal(); resetBaseExplanation(); } /*.................................................................................................................*/ public void addAssistant(TaxaDisplayAssistant tda) { taxaDrawCoordTask.addAssistantTask(tda); TaxaDisplayExtra tce = tda.createTaxaDisplayExtra(taxaDisplay); if (tce==null) return; tce.setTaxa(taxa); taxaDisplay.addExtra(tce); checkLegendPositionsLegal(); taxaDisplay.pleaseUpdate(false); if (getMode()>0) updateTextPage(); } void fileReadIn(){ sizeDisplay(); } /*.................................................................................................................*/ public Snapshot getSnapshot(MesquiteFile file) { Snapshot temp = new Snapshot(); temp.addLine("getTaxaDrawCoordinator", taxaDrawCoordTask); temp.incorporate(super.getSnapshot(file), false); return temp; } /** Returns menu location for item to bring the window to the for (0 = custom or don't show; 1 = system area of Windows menu; 2 = after system area of Windows menu)*/ public int getShowMenuLocation(){ return 0; } /*.................................................................................................................*/ public String getPrintMenuItem() { return "Print Taxa..."; } /*.................................................................................................................*/ public String getPrintToFitMenuItemName() { return "Print Taxa To Fit Page..."; } /* ................................................................................................................. */ public void windowToPDF(MesquitePDFFile pdfFile, int fitToPage) { if (pdfFile != null) { if (infoBar.getMode() > 0) super.windowToPDF(pdfFile, fitToPage); else { Dimension oldtaxaDisplaySize = taxaDisplay.getSize(); taxaDisplay.setPrintingInProcess(true); taxaDisplay.setSize(taxaDisplay.getFieldWidth(), taxaDisplay.getFieldHeight()); //Rectangle r = taxaDisplay.getVisRect(); //taxaDisplay.setVisRect(null); Graphics g2 = pdfFile.getPDFGraphicsForComponent(taxaDisplay, null); taxaDisplay.printAll(g2); taxaDisplay.setSize(oldtaxaDisplaySize.width, oldtaxaDisplaySize.height); //taxaDisplay.setVisRect(r); taxaDisplay.setPrintingInProcess(false); taxaDisplay.repaintAll(); pdfFile.end(); } } } /* ................................................................................................................. */ public String getPrintToPDFMenuItemName() { return "Save Map as PDF..."; } protected void pdfWindow(int fitToPage) { super.pdfWindow(fitToPage); } /*.................................................................................................................*/ public void printWindow(MesquitePrintJob pjob) { if (pjob != null) { if (infoBar.getMode()>0) super.printWindow(pjob); else pjob.printComponent(taxaDisplay, null, null); } } /*.................................................................................................................*/ public void setCurrentTool(MesquiteTool tool){ if (tool!=null && !tool.getEnabled()) return; if (tool instanceof TaxaTool) currentTaxaTool = (TaxaTool)tool; super.setCurrentTool(tool); } /*...............................................................................................................*/ protected void setContentsCursor(Cursor c){ if (c == null) MesquiteMessage.printStackTrace("Error: cursor of taxa window null"); else if (taxaDisplay !=null) taxaDisplay.setCursor(c); } public void setRescaleValue(double rescaleValue) { ListableVector ev = taxaDisplay.getExtras(); taxaDisplay.setRescaleValue(rescaleValue); for (int i=0; i< ev.size(); i++){ TaxaDisplayExtra extra = (TaxaDisplayExtra)ev.elementAt(i); if (extra!=null ) { extra.setRescaleValue(rescaleValue); } } } public void contentsChanged() { if (taxaDrawCoordTask!=null) { double rescaleValue = taxaDrawCoordTask.getRescaleValue(); setRescaleValue(rescaleValue); } super.contentsChanged(); } /*.................................................................................................................*/ MesquiteInteger pos = new MesquiteInteger(); /*.................................................................................................................*/ public Object doCommand(String commandName, String arguments, CommandChecker checker) { if (checker.compare(this.getClass(), "Hires a taxa display assistant module", "[name of assistant module]", commandName, "newAssistant")) { ownerModule.incrementMenuResetSuppression(); TaxaDisplayAssistant tda= (TaxaDisplayAssistant)ownerModule.hireNamedEmployee(TaxaDisplayAssistant.class, arguments); if (tda!=null) { addAssistant(tda); if (!MesquiteThread.isScripting()) ownerModule.resetContainingMenuBar(); } ownerModule.decrementMenuResetSuppression(); return tda; } else if (checker.compare(this.getClass(), "Returns the taxa draw coordinating module", null, commandName, "getTaxaDrawCoordinator")) { return taxaDrawCoordTask; } else if (checker.compare(this.getClass(), "Hires a taxa window assistant module", "[name of assistant module]", commandName, "newWindowAssistant")) { TaxaWindowAssistant tda= (TaxaWindowAssistant)ownerModule.hireNamedEmployee(TaxaWindowAssistant.class, arguments); if (tda!=null) tda.setTaxa(taxa); return tda; } else if (checker.compare(this.getClass(), "Brings the graphics of an assistant module to the front", "[number of assistant module among TaxaDisplayDrawnExtra owners]", commandName, "bringToFront")) { int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; ListableVector ev = taxaDisplay.getExtras(); int count =0; for (int i=0; i< ev.size(); i++){ TaxaDisplayExtra extra = (TaxaDisplayExtra)ev.elementAt(i); if (extra!=null && extra instanceof TaxaDisplayDrawnExtra) { if (count== which) { TaxaDisplayExtra found = extra; ownerModule.moveEmployeeToFront(extra.getOwnerModule()); taxaDisplay.moveExtraToFront(extra); ownerModule.resetContainingMenuBar(); return null; } count++; } } } else if (checker.compare(this.getClass(), "Closes an assistant module", "[number of assistant module]", commandName, "closeDisplayAssistant")) { EmployeeVector ev = ownerModule.getEmployeeVector(); int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; int count =0; for (int i=0; i< ev.size(); i++){ MesquiteModule mb = (MesquiteModule)ev.elementAt(i); if (mb!=null && mb instanceof TaxaDisplayAssistantAD) { if (count== which) { ownerModule.fireEmployee(mb); return null; } count++; } } } else if (checker.compare(this.getClass(), "Saves a macro to redo the analysis of an assistant module", "[number of assistant module]", commandName, "saveMacroDisplayAssistant")) { EmployeeVector ev = ownerModule.getEmployeeVector(); int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; int count =0; for (int i=0; i< ev.size(); i++){ MesquiteModule mb = (MesquiteModule)ev.elementAt(i); if (mb!=null && mb instanceof TaxaDisplayAssistantAD) { if (count== which) { String recipe = "newAssistant #" + mb.getClass().getName() + ";" + StringUtil.lineEnding() + "tell It;"+ StringUtil.lineEnding(); recipe += Snapshot.getSnapshotCommands(mb, null, ""); recipe += "endTell;"+ StringUtil.lineEnding(); MesquiteMacro.saveMacro(ownerModule, "Macro to start " + mb.getNameForMenuItem(), 0, recipe); return null; } count++; } } } else if (checker.compare(this.getClass(), "Requests that the taxa are drawn to a default (suggested) size", null, commandName, "useSuggestedSize")) { //absorbs old scripts } else if (checker.compare(this.getClass(), "Sets whether or not the taxa is drawn so as to fit within the window, or so as to fit within a scrollable pane", "[on or off to indicate whether constrained to window]", commandName, "toggleSizeToFit")) { //absorbs old scripts } else if (checker.compare(this.getClass(), "When Size to Window is false, brings legends into view", null, commandName, "toggleLegendFloat")) { boolean current = floatLegends.getValue(); pos.setValue(0); floatLegends.toggleValue(ParseUtil.getFirstToken(arguments, pos)); if (current != floatLegends.getValue()) toggleLegendFloat(); else checkLegendPositionsLegal(); } else if (checker.compare(this.getClass(), "Sets the size of the drawing pane area (only useful if Size To Fit is turned off)", "[width in pixels of drawing area] [height in pixels of drawing area]", commandName, "sizeDrawing")) { pos.setValue(0); int w = MesquiteInteger.fromString(arguments, pos); int h = MesquiteInteger.fromString(arguments, pos); if (MesquiteInteger.isCombinable(h) && MesquiteInteger.isCombinable(w)) { if (w>10 && h>10) { totalTaxaFieldWidth = w; totalTaxaFieldHeight = h; sizeDisplay(); } } else { MesquiteBoolean answer = new MesquiteBoolean(false); MesquiteInteger newWidth = new MesquiteInteger(totalTaxaFieldWidth); MesquiteInteger newHeight =new MesquiteInteger(totalTaxaFieldHeight); MesquiteInteger.queryTwoIntegers(ownerModule.containerOfModule(), "Size of taxa drawing", "Width (Pixels)", "Height (Pixels)", answer, newWidth, newHeight,10,MesquiteInteger.unassigned,10, MesquiteInteger.unassigned,"Enter the width and height of the taxa drawing. These values must be at least 10 pixels each."); if (answer.getValue() && newWidth.getValue()>10 && newHeight.getValue()>10) { totalTaxaFieldWidth = newWidth.getValue(); totalTaxaFieldHeight = newHeight.getValue(); sizeDisplay(); } } } else if (checker.compare(this.getClass(), "Sets size of taxa window", "[width in pixels of window] [height in pixels of window]", commandName, "setSize")) { MesquiteInteger io = new MesquiteInteger(0); int width= MesquiteInteger.fromString(arguments, io); int height= MesquiteInteger.fromString(arguments, io); if (MesquiteInteger.isCombinable(width) && MesquiteInteger.isCombinable(height)) { fromScriptCommand = true;//this is needed to counteract difficulties with popping in/out and size setting in window constructors setWindowSize(width, height); fromScriptCommand = false; sizeDisplay(); } } else if (checker.compare(this.getClass(), "Sets the origin for the scrolling area", "[origin x] [origin y]", commandName, "setOrigin")) { pos.setValue(0); int horiz = MesquiteInteger.fromString(arguments, pos); int vert = MesquiteInteger.fromString(arguments, pos); if (MesquiteInteger.isCombinable(horiz) && MesquiteInteger.isCombinable(vert)) { setOrigin(horiz, vert, true); } } else if (checker.compare(this.getClass(), "Sets the current tool", "[name of tool]", commandName, "setTool")) { ToolPalette palette = getPalette(); if (palette ==null) return null; currentTaxaTool = (TaxaTool)palette.getToolWithName(arguments); setCurrentTool(currentTaxaTool); setExplanation(currentTaxaTool.getDescription()); } /* else if (checker.compare(this.getClass(), "Zoom image", "[x][y]", commandName, "zoom")) { int x= MesquiteInteger.fromFirstToken(arguments, pos); int y= MesquiteInteger.fromString(arguments, pos); boolean zoomIn = (arguments.indexOf("option")<0); zoom(x,y, zoomIn); }*/ else return super.doCommand(commandName, arguments, checker); return null; } /*.................................................................................................................*/ void zoom(int x, int y, boolean zoomIn){ /* boolean current = sizeToFit.getValue(); int oX = getOriginX(); int oY = getOriginY(); useSuggestedSize.setValue(false); int tW, tH; if (current){ tW = taxaDisplay.getBounds().width; tH = taxaDisplay.getBounds().height; } else { tW = totalTaxaFieldWidth; tH = totalTaxaFieldHeight; } pos.setValue(0); if (current) sizeToFit.setValue(false); int newWidth, newHeight; if (zoomIn){ newWidth = tW*2; newHeight = tH*2; } else { newWidth = tW/2; newHeight = tH/2; } totalTaxaFieldWidth = newWidth; totalTaxaFieldHeight = newHeight; sizeDisplay(); togglePane(false, false); int setX, setY; if (zoomIn) { setX = oX-x; setY = oY-y +scrollWidth; //why is this needed? } else { setX = oX+x/2; setY = oY+y/2; } /* if (zoomIn) setOrigin(-(x+ 2*oX),-(y+2*oY)); else setOrigin(-(oX-x)/2,-(oY-y)/2); setOrigin(setX, setY); //taxaDisplay.getTaxaDrawing().recalculatePositions(taxaDisplay.getTree()); //to force node locs recalc*/ } /*.................................................................................................................*/ public String getTextContents() { if (taxaDisplay==null) return ""; String s = "Taxa window\n"; //if (taxaSourceTask !=null) // s += "Showing " + taxaSourceTask.getNameForMenuItem(); if (taxa!=null) s += " for taxa \"" + taxa.getName() + "\""; s += "\n\n" + taxaDisplay.getTextVersion(); return s; } /*.................................................................................................................*/ public void paintContents(Graphics g) { if (taxaDisplay==null) { MesquiteMessage.warnProgrammer("Oh no, taxa display is null"); } else { //^^^ sizeDisplay(); taxaDisplay.repaint(); checkLegendPositionsLegal(); g.setColor(Color.black); } } /* public void setOrigin(int x, int y, boolean setScrolls) { Debugg.println("*** setOrigin x, y: " + x + ", " + y + " (in setOrigin)"); if (taxaPane !=null) { taxaPane.setScrollPosition(-x,-y); if (setScrolls) { hAdjust.setValue(x); vAdjust.setValue(y); } taxaPane.doLayout(); } initPosX = x; initPosY = y; } */ //for java 1.1 printing public Object fit(Dimension dim){ /*int w; int h; int currentWidth = taxaDisplay.getFieldWidth(); int currentHeight = taxaDisplay.getFieldHeight(); if (currentHeight == 0 || currentWidth == 0) { w = dim.width; h = dim.height; } else if (((double)dim.width)/currentWidth > ((double)dim.height)/currentHeight) { w = (int)(((double)dim.height)/currentHeight * currentWidth); h = dim.height; } else { w = dim.width; h = (int)(((double)dim.width)/currentWidth * currentHeight); } */ Dimension d = new Dimension(getOriginX(), getOriginY()); taxaDisplay.setFieldSize(dim.width,dim.height); setOrigin(0,0, true); taxaDisplay.getTaxaDrawing().recalculatePositions(taxa); //to force node locs recalc return d; } public void unfit(Object o){ int oX = 0; int oY = 0; if (o instanceof Dimension) { oX = ((Dimension)o).width; oY = ((Dimension)o).height; } setOrigin(oX,oY, true); sizeDisplay(); } public int getOriginX() { if (!usingPane) return 0; Point p = getTaxaScrollPoint(); return p.x; // Adjustable h = taxaPane.getHAdjustable(); // return -(int)( ((1.0*(h.getValue()- h.getMinimum()))/(h.getMaximum()-h.getMinimum()))*taxaDisplay.getBounds().width); } public int getOriginY() { if (!usingPane) return 0; Point p = getTaxaScrollPoint(); return p.y; // Adjustable v = taxaPane.getVAdjustable(); // return -(int)( ((1.0*(v.getValue()- v.getMinimum()))/(v.getMaximum()-v.getMinimum()))*taxaDisplay.getBounds().height); } /* public int getOriginX() { if (taxaPane ==null) return 0; Adjustable h = taxaPane.getHAdjustable(); return -(int)( ((1.0*(h.getValue()- h.getMinimum()))/(h.getMaximum()-h.getMinimum()))*taxaDisplay.getBounds().width); } public int getOriginY() { if (taxaPane ==null) return 0; Adjustable v = taxaPane.getVAdjustable(); return -(int)( ((1.0*(v.getValue()- v.getMinimum()))/(v.getMaximum()-v.getMinimum()))*taxaDisplay.getBounds().height); } */ /*_________________________________________________*/ public void InvertTaxa(Graphics g, int M) { if (findTaxon(taxaDisplay.getMouseX(), taxaDisplay.getMouseY()) == M){ //still in taxa g.setColor(Color.black); g.setXORMode(Color.white); taxaDisplay.fillTaxon(g, M); g.setPaintMode(); g.setColor(Color.black); highlightedTaxa=M; } Taxa t = taxaDisplay.getTaxa(); if (t !=null) { if (t.getAnnotation(M)!=null) setAnnotation(t.getAnnotation(M), "Annotation above refers to taxa \"" + t.getTaxonName(M) + "\""); else setExplanation("Taxon: " + t.getTaxonName(M)); } } /*_________________________________________________*/ public void RevertTaxa(Graphics g, int M) { if (highlightedTaxa >= 0){ g.setColor(Color.black); g.setXORMode(Color.white); taxaDisplay.fillTaxon(g, highlightedTaxa); g.setPaintMode(); highlightedTaxa=-1; g.setColor(Color.black); } setAnnotation("", null); } /*_________________________________________________*/ private int getTaxonSymbolNearLocation(int x, int y){ for (int it=0; it= 0) { if (taxonFound==-1) { notifyExtrasOfTaxaExit(g, highlightedTaxa); RevertTaxa(g, highlightedTaxa); setExplanation(baseExplanation, false); //revert explanation to default one } else if (taxonFound!=highlightedTaxa) { notifyExtrasOfTaxaExit(g, highlightedTaxa); RevertTaxa(g, highlightedTaxa); notifyExtrasOfTaxaEnter(g, taxonFound); InvertTaxa(g, taxonFound); } else currentTaxaTool.taxonMoveOver(taxonFound, modifiers); } else if (taxonFound!=-1 && !currentTaxaTool.getIgnoreTaxa()) { currentTaxaTool.taxonMoveOver(taxonFound, modifiers); notifyExtrasOfTaxaEnter(g, taxonFound); InvertTaxa(g, taxonFound); } else { currentTaxaTool.moved(x,y,modifiers); //notify extras? } } int oldX=MesquiteInteger.unassigned; int oldY=MesquiteInteger.unassigned; int newX=MesquiteInteger.unassigned; int newY=MesquiteInteger.unassigned; static final int dotSize = 8; /*.................................................................................................................*/ public void firstDot(Graphics g) { Composite composite = ColorDistribution.getComposite(g); ColorDistribution.setTransparentGraphics(g); if (MesquiteInteger.isCombinable(oldX) && MesquiteInteger.isCombinable(oldY)){ //erase old one g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2,false); } g.setPaintMode(); g.setColor(Color.black); ColorDistribution.setComposite(g,composite); } /*.................................................................................................................*/ public void moveDot(Graphics g) { Composite composite = ColorDistribution.getComposite(g); ColorDistribution.setTransparentGraphics(g); if (MesquiteInteger.isCombinable(oldX) && MesquiteInteger.isCombinable(oldY)){ //erase old one g.setXORMode(Color.gray); // g.setColor(Color.black); // g.drawOval(oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2); g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2,false); } if (MesquiteInteger.isCombinable(newX) && MesquiteInteger.isCombinable(newY)){ //erase old one g.setXORMode(Color.gray); // g.setColor(Color.black); // g.drawOval(newX-dotSize, newY-dotSize, dotSize*2, dotSize*2); g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,newX-dotSize, newY-dotSize, dotSize*2, dotSize*2,false); } g.setPaintMode(); g.setColor(Color.black); ColorDistribution.setComposite(g,composite); } /*.................................................................................................................*/ int taxonTouched = MesquiteInteger.unassigned; /*_________________________________________________*/ public void ScanDrop(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxaDrawCoordTask == null || taxaDrawCoordTask.getNamesTask() == null || taxaDisplay.getTaxaDrawing()==null) return; if (taxaDisplay.getInvalid()) return; xFrom = -1; yFrom = -1; xTo = -1; yTo = -1; int nameFound = findTaxon(x,y); if (MesquiteInteger.isCombinable(taxonTouched)){ newX=MesquiteInteger.unassigned; newY=MesquiteInteger.unassigned; moveDot(g); currentTaxaTool.taxonMouseUp(taxonTouched, x,y,modifiers); } else if (nameFound==-1 || currentTaxaTool.getIgnoreTaxa()) { boolean fieldMouseUpAccepted = currentTaxaTool.fieldMouseUp(x,y,modifiers); } //return false; } /*_________________________________________________*/ public boolean ScanTouch(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxaDrawCoordTask == null || taxaDrawCoordTask.getNamesTask() == null || taxaDisplay.getTaxaDrawing()==null) return false; if (taxaDisplay.getInvalid()) return false; xFrom = -1; yFrom = -1; xTo = -1; yTo = -1; oldX=MesquiteInteger.unassigned; oldY=MesquiteInteger.unassigned; newX=MesquiteInteger.unassigned; newY=MesquiteInteger.unassigned; taxonTouched = MesquiteInteger.unassigned; int nameFound = findTaxon(x,y); if (nameFound!=-1 && !currentTaxaTool.getIgnoreTaxa()) { currentTaxaTool.taxonTouched(nameFound, modifiers); notifyExtrasOfTaxaTouch(g, nameFound); if (highlightedTaxa >= 0 ) RevertTaxa(g, highlightedTaxa); taxonTouched = nameFound; //oldX = x; //oldY = y; //firstDot(g); return true; } else { boolean fieldTouchAccepted=true; fieldTouchAccepted = currentTaxaTool.fieldTouched(x,y,modifiers); //notify extras? return fieldTouchAccepted; } //return false; } /*_________________________________________________*/ public void ScanDrag(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxa == null) return; if (taxaDisplay.getInvalid()) return; if (MesquiteInteger.isCombinable(taxonTouched)) { newX = x; newY = y; moveDot(g); oldX = x; oldY = y; currentTaxaTool.taxonDragged(taxonTouched,x,y,modifiers); } // fill out DRM: } /*................................................................................................*/ public void notifyExtrasOfTaxaEnter(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorEnterTaxon(M, g); } } } } /*................................................................................................*/ public void notifyExtrasOfTaxaExit(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorExitTaxon( M, g); } } } } /*................................................................................................*/ public void notifyExtrasOfTaxaTouch(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorTouchTaxon(M, g); } } } } /*.................................................................................................................*/ /** passes which object is being disposed (from MesquiteListener interface)*/ public void disposing(Object obj){ if (obj instanceof Taxa && (Taxa)obj ==taxa) { ownerModule.iQuit(); } } /*.................................................................................................................*/ /** passes which object is being disposed (from MesquiteListener interface)*/ public boolean okToDispose(Object obj, int queryUser){ return true; //TODO: respond } /*.................................................................................................................*/ /** passes which object changed (from MesquiteListener interface)*/ public void changed(Object caller, Object obj, Notification notification){ int code = Notification.getCode(notification); int[] parameters = Notification.getParameters(notification); if (obj instanceof Taxa && (Taxa)obj ==taxa) { if (code==MesquiteListener.TAXA_DRAWING_SIZING_CHANGED) { windowResized(); canUndo = false; taxaDisplay.pleaseUpdate(true); } else if (code==MesquiteListener.PARTS_CHANGED || code ==MesquiteListener.PARTS_ADDED || code == MesquiteListener.PARTS_MOVED || code == MesquiteListener.PARTS_DELETED) { canUndo = false; taxaDisplay.pleaseUpdate(true); } else if (code==MesquiteListener.NAMES_CHANGED || code == MesquiteListener.SELECTION_CHANGED || code == AssociableWithSpecs.SPECSSET_CHANGED) taxaDisplay.pleaseUpdate(true); if (getMode()>0) updateTextPage(); } super.changed(caller, obj, notification); } /*.................................................................................................................*/ void resetBaseExplanation(){ String td = ""; String td2 = ""; if (ownerModule.getProject().getNumberTaxas()>1) td += "Taxa window shows taxa \"" + taxa.getName() + "\"\n"; baseExplanation.setValue(td + "Browsing Mode. " + td2 + "The taxa shown are from " + taxa.getName()); setExplanation(baseExplanation, true); } /*.................................................................................................................*/ public void setExplanation(String exp){ baseExplanationUsed = false; super.setExplanation(exp); } /*.................................................................................................................*/ void setExplanation(MesquiteString exp, boolean setEvenIfAlreadyBase){ if (exp == null) return; if (exp != baseExplanation || !(baseExplanationUsed && !setEvenIfAlreadyBase)) { baseExplanationUsed = true; super.setExplanation(exp.toString()); } } /* ................................................................................................................. */ public void windowResized() { super.windowResized(); if (!MesquiteThread.isScripting() || (windowModule != null && windowModule.respondToWindowResize)) sizeDisplay(); if (taxaDrawCoordTask!=null) { taxaDrawCoordTask.setRescaleValue(); double rescaleValue = taxaDrawCoordTask.getRescaleValue(); setRescaleValue(rescaleValue); } } /*.................................................................................................................*/ public void dispose(){ disposing = true; waitUntilDisposable(); if (taxa!=null) taxa.removeListener(this); windowModule = null; if (currentTaxaTool!=null) { currentTaxaTool.dispose(); currentTaxaTool = null; } taxaDrawCoordTask = null; // taxaSourceTask = null; if (taxaDisplay !=null){ removeFromWindow(taxaDisplay); taxaDisplay.dispose(); } taxaDisplay=null; //if (rooted!=null) // rooted.releaseMenuItem(); super.dispose(); } } /* ======================================================================== */ class REALTaxaScrollPane extends ScrollPane{ BasicTaxaWindow window; public REALTaxaScrollPane (int scrollPolicy, BasicTaxaWindow window) { super(scrollPolicy); this.window = window; } public void addTaxaDisplay(Component c){ addImpl(c, null, 0); } public void setSize(int w, int h){ super.setSize(w, h); window.checkLegendPositionsLegal(); } public void setScrollPosition(int x, int y) { //Debugg.println(" setScrollPosition x,y " + x + ", " + y );; super.setScrollPosition(x,y); } public void setScrollPosition(Point p) { //Debugg.println(" setScrollPosition p " + p);; super.setScrollPosition(p); } public void setBounds(int x, int y, int w, int h){ super.setBounds(x, y, w, h); window.checkLegendPositionsLegal(); } } /* ======================================================================== */ /* * this is an attempt to get around the bug in OS X java 1.4+ in which ScrollPane scrollbars don't return their position and don't notify of adjustments. This faux-ScrollPane works reasonably well but is slower and has some graphical artifacts */ class TaxaScrollPane extends Panel implements MouseWheelListener { // HANDMADETreeScrollPane BasicTaxaWindow window; TaxaScroll hScroll, vScroll; Panel port; Component taxaDisplay; public TaxaScrollPane(BasicTaxaWindow window) { super(); hScroll = new TaxaScroll(this, Scrollbar.HORIZONTAL, 0, 2, 0, 0); vScroll = new TaxaScroll(this, Scrollbar.VERTICAL, 0, 2, 0, 0); setLayout(new BorderLayout()); add(hScroll, BorderLayout.SOUTH); add(vScroll, BorderLayout.EAST); add(port = new Panel(), BorderLayout.CENTER); addMouseWheelListener(this); port.setLayout(null); doLayout(); this.window = window; } public void addTaxaDisplay(Component c) { port.add(c); taxaDisplay = c; } public boolean isFauxScrollPane() { return true; } public Adjustable getHAdjustable() { return hScroll; } public Adjustable getVAdjustable() { return vScroll; } public void setHMinMax(int min, int max) { if (min < 0) min = 0; if (max < min) max = min; boolean touch = hScroll.setMinimumWithResetWarning(min); touch = hScroll.setMaximumWithResetWarning(max) || touch; if (touch) scrollTouched(null, 0); //Debugg.println("\nHMinMax " + min + " " + max); hScroll.setVisible(min != max); if (min == max) taxaDisplay.setLocation(0, taxaDisplay.getLocation().y); } public void setVMinMax(int min, int max) { if (min < 0) min = 0; if (max < min) max = min; boolean touch = vScroll.setMinimumWithResetWarning(min); touch = vScroll.setMaximumWithResetWarning(max) || touch; if (touch) scrollTouched(null, 0); vScroll.setVisible(min != max); //Debugg.println("\nVMinMax " + min + " " + max); if (min == max) taxaDisplay.setLocation(taxaDisplay.getLocation().x, 0); } public void scrollTouched(TaxaScroll scroll, int value) { window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); constrainTaxaDisplay(); } public Dimension getViewportSize() { return new Dimension(port.getWidth(), port.getHeight()); } public int getContentsWidth() { return port.getWidth(); } public int getContentsHeight() { return port.getHeight(); } public Point getScrollPosition() { return new Point(hScroll.getValue(), vScroll.getValue()); } public void setScrollPosition(int h, int v) { hScroll.setValue(h); vScroll.setValue(v); } public void constrainTaxaDisplay() { // post 2. 6 needed at least for OS X as workaround for JVM failure to respect bounds of containing panel if (taxaDisplay == null) return; int w = port.getWidth(); int h = port.getHeight(); int wReduce = 0; int hReduce = 0; if (taxaDisplay.getWidth() + taxaDisplay.getX() != w) wReduce = taxaDisplay.getWidth() + taxaDisplay.getX() - w; if (taxaDisplay.getHeight() + taxaDisplay.getY() != h) hReduce = taxaDisplay.getHeight() + taxaDisplay.getY() - h; if (wReduce != 0 || hReduce != 0) taxaDisplay.setSize(taxaDisplay.getWidth() - wReduce, taxaDisplay.getHeight() - hReduce); } public void setSize(int w, int h) { super.setSize(w, h); doLayout(); constrainTaxaDisplay(); window.checkPanelPositionsLegal(); } public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); doLayout(); constrainTaxaDisplay(); window.checkPanelPositionsLegal(); } public void mouseWheelMoved(MouseWheelEvent e) { int amount = e.getScrollAmount() * 2; boolean blockScroll = e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL; boolean vert = !e.isShiftDown(); boolean upleft = e.getWheelRotation() < 0; if (vert) { if (blockScroll) amount = vScroll.getBlockIncrement(); else amount = vScroll.getUnitIncrement() * amount; if (upleft) { amount = -amount; if (vScroll.getValue() == 0) amount = 0; } if (amount != 0) { vScroll.setValue(vScroll.getValue() + amount); //window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); window.sizeDisplay(); } } else { if (blockScroll) amount = hScroll.getBlockIncrement(); else amount = hScroll.getUnitIncrement() * amount; if (upleft) { amount = -amount; if (hScroll.getValue() == 0) amount = 0; } if (amount!=0) { hScroll.setValue(hScroll.getValue()); //window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); window.sizeDisplay(); } } } } /* ======================================================================== * class LockPanel extends MousePanel { Image lockClosed, lockOpen, lockImage; BasicTaxaWindow window; int state; public LockPanel(BasicTaxaWindow window){ super(); this.window = window; lockClosed = MesquiteImage.getImage(MesquiteModule.getRootPath() + "images/lockClosed.gif"); lockOpen = MesquiteImage.getImage(MesquiteModule.getRootPath() + "images/lockOpen.gif"); setLockState(0); } public void setLockState(int state){ this.state = state; if (state == 0) lockImage = lockClosed; else if (state ==1) lockImage = lockClosed; else if (state == 2) lockImage = lockOpen; } public void paint(Graphics g) { //^^^ if (MesquiteWindow.checkDoomed(this)) return; g.drawImage(lockImage, 0, -1, this); g.drawLine(0, getBounds().height-1, getBounds().width, getBounds().height-1); MesquiteWindow.uncheckDoomed(this); } public void mouseUp(int modifiers, int x, int y, MesquiteTool tool) { window.lockTouched(); repaint(); } } */ /* ======================================================================== */ class MessagePanel extends Panel { String message; MesquiteModule ownerModule; boolean showDiamond = false; boolean indicateModified; String modifiedString = ""; Polygon poly; int left = 4; int top = 4; int s = 8; public MessagePanel(MesquiteModule ownerModule) { //in future pass general MesquiteWindow super(); message=""; poly = new Polygon(); poly.xpoints = new int[4]; poly.ypoints = new int[4]; poly.npoints=0; poly.addPoint(left, top+s/2); poly.addPoint(left + s/2, top); poly.addPoint(left + s, top+s/2); poly.addPoint(left + s/2, top+s); poly.npoints=4; this.ownerModule = ownerModule; setBackground(ColorTheme.getInterfaceElement()); } public void paint(Graphics g) { if (MesquiteWindow.checkDoomed(this)) return; g.drawRect(0,0, getBounds().width -1, getBounds().height-1); if (showDiamond){ g.fillPolygon(poly); if (message != null) g.drawString(modifiedString + message, left + s + 4, 12); } else if (message != null) g.drawString(modifiedString + message, 4, 12); MesquiteWindow.uncheckDoomed(this); } public void setMessage(String s) { message = s; repaint(); } public void setHighlighted(boolean showDiamond, boolean showGreen, boolean indicateModified) { this.showDiamond = showDiamond; if (indicateModified) modifiedString ="Modified from "; else modifiedString = ""; if (showGreen) setBackground(ColorDistribution.lightGreen); else setBackground(ColorTheme.getInterfaceElement()); repaint(); } } /* ======================================================================== */ /* scrollbar for taxa */ class TaxaScroll extends MesquiteScrollbar { TaxaScrollPane tsp; public TaxaScroll (TaxaScrollPane tsp, int orientation, int value, int visible, int min, int max){ super(orientation, value, visible, min, max); this.tsp = tsp; } public boolean setMinimumWithResetWarning(int m) { boolean resetNeeded = false; if (getValue() < m) { setValue(m); resetNeeded = true; } super.setMinimum(m); return resetNeeded; } public boolean setMaximumWithResetWarning(int m) { boolean resetNeeded = false; if (getValue() > m) { setValue(m); resetNeeded = true; } super.setMaximum(m); return resetNeeded; } public void scrollTouched() { int currentValue = getValue(); tsp.scrollTouched(this, currentValue); } public boolean processDuringAdjustment() { return true; } public void print(Graphics g) { } } /* ======================================================================== * class MagnifyExtra extends TaxaDisplayExtra { Image image; public MagnifyExtra (MesquiteModule ownerModule, TaxaDisplay taxaDisplay, TaxaTool tool) { super(ownerModule, taxaDisplay); image = MesquiteImage.getImage(tool.getImagePath()); } /*.................................................................................................................* public void drawOntaxa(Tree tree, int drawnRoot, Graphics g) { if (drawnRoot!= tree.getRoot()) { TaxaDrawing td = taxaDisplay.getTaxaDrawing(); g.drawImage(image, td.x[drawnRoot], td.y[drawnRoot], taxaDisplay); } } public void setTree(Tree tree) { } /** Returns any strings to be appended to taxa name.* public String getTaxaStringAddition(Taxa taxa){ Taxa taxa = taxa.getTaxa(); int which = taxa.whichTaxaNumber(taxa); String s = taxa.getAnnotation(which); if (!StringUtil.blank(s)) return "*"; return null; } public void printOnTree(Tree tree, int drawnRoot, Graphics g) { } } */ \ No newline at end of file +/* Mesquite.cartographer source code. Copyright 2008-2009 D. Maddison and W. Maddison. Version 1.3, June 2008. Disclaimer: The Mesquite source code is lengthy and we are few. There are no doubt inefficiencies and goofs in this code. The commenting leaves much to be desired. Please approach this source code with the spirit of helping out. Perhaps with your help we can be more than a few, and make Mesquite better. Mesquite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Mesquite's web site is http://mesquiteproject.org This source code and its compiled class files are free and modifiable under the terms of GNU Lesser General Public License. (http://www.gnu.org/copyleft/lesser.html) */ package mesquite.cartographer.BasicTaxaWindowMaker; /*~~ */ import java.util.*; import java.awt.*; import java.awt.event.*; import mesquite.lib.*; import mesquite.lib.duties.*; /** Makes and manages a Taxa Window for taxa editing and visualization */ public class BasicTaxaWindowMaker extends TaxaWindowMaker implements CommandableOwner, TaxaDisplayActive { public DrawTaxaCoordinator taxaDrawCoordTask; // public TaxaSource taxaSourceTask; public Vector contextListeners; Taxa taxa; static boolean warnUnsaved; BasicTaxaWindow basicTaxaWindow; // MesquiteString taxaSourceName; // MesquiteCommand tsC; static { warnUnsaved = true; } /*...................................................................................................................*/ public boolean startJob(String arguments, Object condition, boolean hiredByName) { loadPreferences(); makeMenu("Taxa"); /* taxaSourceTask= (TaxaSource)hireCompatibleEmployee(TaxaSource.class, condition, "Source of taxa (Taxa window)"); if (taxaSourceTask == null) return sorry(getName() + " couldn't start because no source of taxa was obtained."); taxaSourceName = new MesquiteString(taxaSourceTask.getName()); tsC = makeCommand("setTaxaSource", this); taxaSourceTask.setHiringCommand(tsC); defineMenus(false); */ if (MesquiteThread.isScripting() && getProject().developing) respondToWindowResize = false; // this prevents a lot of tree/window resizing when file being re-read contextListeners = new Vector(); //setAutoSaveMacros(true); return true; } boolean respondToWindowResize = true; public void fileReadIn(MesquiteFile f) { respondToWindowResize = true; if (basicTaxaWindow != null) { basicTaxaWindow.fileReadIn(); } } /*--------------------------------------*/ public boolean isPrerelease(){ return false; } // public String getExpectedPath(){ // return getPath() + "recent"; // } /*--------------------------------------*/ /*Menus defined in this method are visible to Mesquite's automatic documentation system (overrides method of MesquiteModule)* public void defineMenus(boolean accumulating){ if (accumulating || numModulesAvailable(TaxaSource.class)>1) { MesquiteSubmenuSpec mss = addSubmenu(null, "Taxa Source", tsC); if (!accumulating){ mss.setSelected(taxaSourceName); mss.setList(TaxaSource.class); if (taxa !=null) mss.setCompatibilityCheck(taxa); } } } /*--------------------------------------*/ public Commandable[] getCommandablesForAccumulation(){ Commandable[] cs = new Commandable[1]; cs[0]= new BasicTaxaWindow(); return cs; } public void employeeQuit(MesquiteModule m){ if (basicTaxaWindow!=null) basicTaxaWindow.contentsChanged(); } public void processPreferencesFromFile (String[] prefs) { if (prefs!=null && prefs.length>0) { if (prefs[0].equals("warned")) { warnUnsaved = false; } } } /*.................................................................................................................*/ public String preparePreferencesForXML () { StringBuffer buffer = new StringBuffer(); StringUtil.appendXMLTag(buffer, 2, "warnUnsaved", warnUnsaved); return buffer.toString(); } /*.................................................................................................................*/ public void processSingleXMLPreference (String tag, String content) { if ("warnUnsaved".equalsIgnoreCase(tag)) warnUnsaved = MesquiteBoolean.fromTrueFalseString(content); } /*.................................................................................................................*/ public Snapshot getSnapshot(MesquiteFile file) { if (basicTaxaWindow==null) return null; Snapshot temp = new Snapshot(); Snapshot fromWindow = basicTaxaWindow.getSnapshot(file); // temp.addLine("setTaxaSource " , taxaSourceTask); temp.addLine("setAssignedID " + getPermanentIDString()); //for taxa context temp.addLine("getTaxaWindow"); temp.addLine("tell It"); temp.incorporate(fromWindow, true); for (int i = 0; i2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 Shape c = g.getClip(); g.setClip(0, 0, 99999, 99999); if (basicTaxaWindow.isFauxScrollPane()) g.setClip(basicTaxaWindow.getTaxaViewport()); boolean st = basicTaxaWindow.ScanTouch(g, x, y, modifiers); g.setClip(c); return st; } /*.................................................................................................................*/ public boolean mouseUpInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanDrop( g, x, y, modifiers); return true; } /*.................................................................................................................*/ public boolean mouseMoveInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanFlash(g, x, y, modifiers); //basicTaxaWindow.setExplanation(basicTaxaWindow.baseExplanation, false); return true; } /*.................................................................................................................*/ public boolean mouseDragInTaxaDisplay(int modifiers, int x, int y, TaxaDisplay taxaDisplay, Graphics g) { if (x>2000000 || y> 2000000) return true; //here because of bug in Mac OS X 10.0.4 basicTaxaWindow.ScanDrag(g, x, y, modifiers); return true; } /*.................................................................................................................*/ /**Returns command to hire employee if clonable*/ public String getClonableEmployeeCommand(MesquiteModule employee){ if (employee!=null && employee.getEmployer()==this) { if (employee.getHiredAs()==TaxaWindowAssistant.class) return ("newWindowAssistant " + StringUtil.tokenize(employee.getName()) + ";");//quote if (employee.getHiredAs()==TaxaDisplayAssistant.class) return ("newAssistant " + StringUtil.tokenize(employee.getName()) + ";");//quote } return null; } } /* ======================================================================== */ class BasicTaxaWindow extends MesquiteWindow implements Fittable, MesquiteListener, AdjustmentListener { TaxaDisplay taxaDisplay; boolean properlyFormed = false; Taxa taxa; DrawTaxaCoordinator taxaDrawCoordTask; boolean taxaEdited=false; TaxaScrollPane taxaPane; Adjustable hScroll, vScroll; boolean usingPane = false; boolean scaleToFit = false; // TaxaSource taxaSourceTask; boolean warningGivenForTaxaSource = false; static final int scrollWidth = 16; static final int initalWindowHeight = 400; static final int initalWindowWidth = 520; static final int baseMessageWidth = 256; int messageWidth = 256; int totalTaxaFieldWidth = 800; int totalTaxaFieldHeight = 800; MessagePanel messagePanel; boolean canUndo = true; TaxaTool currentTaxaTool; MesquiteBoolean floatLegends; BasicTaxaWindowMaker windowModule; int highlightedTaxa=-1; int xFrom, yFrom, xTo, yTo; boolean usingDefaultBush = false; //MesquiteMenuItemSpec sizeItem; static int numWindows=0; private int windowNum=0; int initPosX = 0; int initPosY = 0; // long treeVersion = 0; MesquiteString baseExplanation; boolean baseExplanationUsed=false; // boolean treeAnnotationShown = false; MesquiteMenuItemSpec floatLegendsItem; int oldH = 0; int oldV = 0; boolean showTaxaListOnSave = false; //have preference for this? Dimension oldPreferred = null; /*When lockStoredTrees is true (MacClade mode), editing a stored tree causes the tree to be treated as unsaved, and for the new tree to be saved, Store Tree or Replace Stored Tree must be called. When false, editing a stored tree changes the original in storage.*/ //boolean lockStoredTrees = false; //LockPanel lockPanel; public BasicTaxaWindow(){ } public BasicTaxaWindow ( BasicTaxaWindowMaker ownerModule, Taxa taxa){ super(ownerModule, true); //INFOBAR setWindowSize(initalWindowWidth,initalWindowHeight); ownerModule.setModuleWindow(this); baseExplanation = new MesquiteString(""); numWindows++; windowNum=numWindows; windowModule = ownerModule; this.taxa=taxa; TaxaTool tool1 = new TaxaTool(this, "arrow", MesquiteModule.getRootImageDirectoryPath(), "arrow.gif", 4,2,"Arrow Tool", "This is the standard arrow tool."); tool1.setTouchedCommand(MesquiteModule.makeCommand("touchTaxa", this)); currentTaxaTool = tool1; addTool(tool1); setCurrentTool(currentTaxaTool); currentTaxaTool.setInUse(true); currentTaxaTool.setIsArrowTool(true); taxaDrawCoordTask= windowModule.hireTaxaDrawCoordTask(); if (taxaDrawCoordTask==null) return; this.ownerModule = ownerModule; // this.taxaSourceTask=tsT; floatLegends = new MesquiteBoolean(true); if (taxa!=null) { taxa.addListener(this); } taxaDisplay =taxaDrawCoordTask.createOneTaxaDisplay(taxa, this); taxaDisplay.setLocation(0, 0); ownerModule.addModuleMenuItems(null, ownerModule.makeCommand("newWindowAssistant", this), TaxaWindowAssistantN.class); ownerModule.addModuleMenuItems(null, ownerModule.makeCommand("newAssistant", this), TaxaDisplayAssistantD.class); // ownerModule.addMenuItem( "-", null); MesquiteSubmenuSpec mBringToFrontAsst = ownerModule.addSubmenu(null, "Bring To Front"); mBringToFrontAsst.setList(taxaDisplay.getExtras()); mBringToFrontAsst.setListableFilter(TaxaDisplayDrawnExtra.class); mBringToFrontAsst.setCommand(ownerModule.makeCommand("bringToFront", this)); MesquiteSubmenuSpec mSaveMacroAsst = ownerModule.addSubmenu(null, "Save Taxa Analysis as Macro"); mSaveMacroAsst.setList(ownerModule.getEmployeeVector()); mSaveMacroAsst.setListableFilter(TaxaDisplayAssistantAD.class); mSaveMacroAsst.setCommand(ownerModule.makeCommand("saveMacroDisplayAssistant", this)); MesquiteSubmenuSpec mCloseAsst = ownerModule.addSubmenu(null, "Close/Remove"); mCloseAsst.setList(ownerModule.getEmployeeVector()); mCloseAsst.setListableFilter(TaxaDisplayAssistantAD.class); mCloseAsst.setCommand(ownerModule.makeCommand("closeDisplayAssistant", this)); taxaDrawCoordTask.addMenuItem("-", null); //taxaDrawCoordTask.addCheckMenuItem(null, "Use Suggested Size", ownerModule.makeCommand("useSuggestedSize", this), useSuggestedSize); // taxaDrawCoordTask.addCheckMenuItem(null, "Size To Window", ownerModule.makeCommand("toggleSizeToFit", this), sizeToFit); // sizeItem = taxaDrawCoordTask.addMenuItem("Drawing Size...", MesquiteModule.makeCommand("sizeDrawing", this)); floatLegendsItem = taxaDrawCoordTask.addCheckMenuItem(null, "Float Legends", ownerModule.makeCommand("toggleLegendFloat", this), floatLegends); taxaDisplay.setTaxa(taxa); taxaDisplay.setTaxonNameBuffer(30); messagePanel=new MessagePanel(ownerModule); addToWindow(messagePanel); messagePanel.setVisible(true); /* lockPanel=new LockPanel(this); addToWindow(lockPanel); lockPanel.setLocation(0, getHeight()-scrollWidth); lockPanel.setVisible(true); */ //setBackground(Color.white); setBackground(ColorTheme.getInterfaceElement()); messagePanel.setLocation(0, getHeight()-scrollWidth); //togglePane(true, true); taxaPane = new TaxaScrollPane(this); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); hScroll.addAdjustmentListener(this); vScroll.addAdjustmentListener(this); taxaDisplay.setVisible(true); ownerModule.hireAllEmployees(TaxaWindowAssistantI.class); Enumeration em = ownerModule.getEmployeeVector().elements(); while (em.hasMoreElements()) { Object obj = em.nextElement(); MesquiteModule mb = (MesquiteModule)obj; if (mb instanceof TaxaWindowAssistant) { ((TaxaWindowAssistant)mb).setTaxa(taxa); } } setShowExplanation(true); setShowAnnotation(true); baseExplanation.setValue("This is a taxa window. In it you can view taxa from various taxa sources."); setExplanation(baseExplanation, true); // taxaWindowTask.doCommand("makeTaxaWindow", getProject().getTaxaReferenceInternal(taxa), checker); sizeDisplay(); resetTitle(); doCommand("useSuggestedSize",null, CommandChecker.defaultChecker); properlyFormed = true; } /*.................................................................................................................*/ public boolean getProperlyFormed(){ return properlyFormed; } /*.................................................................................................................*/ /** When called the window will determine its own title. MesquiteWindows need to be self-titling so that when things change (names of files, tree blocks, etc.) they can reset their titles properly*/ public void resetTitle(){ String t; t = "Taxa Window " + windowNum + " for taxa \"" +taxa.getName() + "\""; //else // t = "Taxa Window " + windowNum + " showing " + taxaSourceTask.getNameForMenuItem(); setTitle(t); } private void toggleLegendFloat(){ if (taxaPane == null || floatLegends.getValue()) { //legends can't float checkLegendPositionsLegal(); } else { //undoing floating //get bounds on visible part of taxaDisplay Point pt = taxaPane.getScrollPosition(); Dimension dim = taxaPane.getViewportSize(); //cycle through all components getting those that are Legends Component[] cc = taxaDisplay.getComponents(); if (cc!=null && cc.length>0) for (int i=0; i dim.width /2) { //move legend to right border legend.setOffsetX(taxaDisplay.getBounds().width - dim.width + legend.getOffsetX()); done = true; } else { //move legend to left border legend.setOffsetX(legend.getOffsetX() - pt.x); done = true; } if (rect.y - pt.y > dim.height/2){ //move legend to bottom border legend.setOffsetY(taxaDisplay.getBounds().height - dim.height + legend.getOffsetY()); done = true; } else { //move legend to left border legend.setOffsetY(legend.getOffsetY() - pt.y); done = true; } if (done) legend.adjustLocation(); } } checkLegendPositionsLegal(); } } void checkLegendPositionsLegal(){ if (taxaDisplay == null) return; try { if (taxaPane == null || !floatLegends.getValue()) { //legends can't float or aren't floating Component[] cc = taxaDisplay.getComponents(); if (cc!=null && cc.length>0) for (int i=0; i0) for (int i=0; i pt.x+dim.width) { //move legend left amountX = - rect.x - rect.width + (pt.x+dim.width); } else if (rect.x pt.y+dim.height){ //move legend up amountY = -rect.y - rect.height + ( pt.y+dim.height); } else if (rect.y0) for (int i=0; i0) for (int i=0; i 0) for (int i = 0; i < cc.length; i++) { if (cc[i] instanceof Legend) { Legend legend = (Legend) cc[i]; legend.setOffsetX(legend.getOffsetX() + changeH); legend.setOffsetY(legend.getOffsetY() + changeV); legend.adjustLocation(); } } } oldH = hScroll.getValue(); oldV = vScroll.getValue(); } else checkPanelPositionsLegal(); } /*.................................................................................................................*/ boolean isFauxScrollPane() { if (usingPane) return taxaPane.isFauxScrollPane(); return false; } Rectangle getTaxaViewport() { if (usingPane && hScroll != null) { if (!isFauxScrollPane() && MesquiteTrunk.isMacOSX()) return new Rectangle(0, 0, taxaDisplay.getWidth(), taxaDisplay.getHeight()); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); return new Rectangle(hScroll.getValue(), vScroll.getValue(), taxaPane.getContentsWidth(), taxaPane.getContentsHeight()); // SCROLLPANEreturn taxaPane.getViewportSize(); } else return new Rectangle(0, 0, taxaDisplay.getWidth(), taxaDisplay.getHeight()); } Dimension getTaxaViewportSize() { if (usingPane) return taxaPane.getViewportSize(); // SCROLLPANEreturn taxaPane.getViewportSize(); else return new Dimension(taxaDisplay.getWidth(), taxaDisplay.getHeight()); } Point getTaxaScrollPoint() { if (usingPane) return taxaPane.getScrollPosition(); // SCROLLPANEreturn taxaPane.getScrollPosition(); else return new Point(0, 0); } int getTaxaPaneWidth() { if (usingPane) return taxaPane.getBounds().width; else return taxaDisplay.getBounds().width; } int getTaxaPaneHeight() { if (usingPane) return taxaPane.getBounds().height; else return taxaDisplay.getBounds().height; } /* ................................................................................................................. */ public void togglePane(boolean paneOn, boolean resetOrigin) { if (paneOn) { if (!usingPane) { messageWidth = baseMessageWidth; removeFromWindow(taxaDisplay); addToWindow(taxaPane); taxaPane.setLocation(0, 0); taxaPane.addTaxaDisplay(taxaDisplay); usingPane = true; taxaPane.setSize(getWidth(), getHeight() - scrollWidth); hScroll = taxaPane.getHAdjustable(); vScroll = taxaPane.getVAdjustable(); hScroll.setUnitIncrement(10); hScroll.setBlockIncrement((getWidth() - scrollWidth) / 10); /* * hScroll.setBounds(0, getHeight()-scrollWidth-scrollWidth, getWidth()-scrollWidth, scrollWidth); vScroll.setBounds(getWidth()-scrollWidth, 0, scrollWidth, getHeight()-scrollWidth-scrollWidth); */ vScroll.setBlockIncrement((getHeight() - scrollWidth) / 10); vScroll.setUnitIncrement(10); resetScrolls(); oldH = hScroll.getValue(); oldV = vScroll.getValue(); floatLegendsItem.setEnabled(true); // if (!initiating) { ownerModule.resetContainingMenuBar(); // taxaPane.setVisible(true); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); // lockPanel.repaint(); // } setOrigin(0, 0, true); // initiating = false; taxaPane.doLayout(); } } else { if (usingPane) { usingPane = false; removeFromWindow(taxaPane); addToWindow(taxaDisplay); if (floatLegendsItem != null) floatLegendsItem.setEnabled(false); // if (!initiating) { taxaPane.setSize(getWidth(), getHeight() - scrollWidth); ownerModule.resetContainingMenuBar(); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); taxaDisplay.setLocation(0, 0); /* End new code added Feb.07 oliver */ // lockPanel.repaint(); // } // initiating = false; } if (resetOrigin) setOrigin(0, 0, true); } taxaDisplay.setVisRect(getTaxaViewport()); } public void setOrigin(int x, int y, boolean setScrolls) { if (x < 0) x = 0; if (y < 0) y = 0; if (usingPane) { taxaDisplay.setLocation(-x, -y); if (setScrolls) { hScroll.setValue(x); vScroll.setValue(y); } taxaDisplay.setVisRect(getTaxaViewport()); } resetLegends(); } public void resetScrolls() { if (hScroll.getValue() < 0) hScroll.setValue(0); if (vScroll.getValue() < 0) { vScroll.setValue(0); } } /*.................................................................................................................* public void togglePane(boolean initiating) { togglePane(initiating, true); } /*.................................................................................................................* public void togglePane(boolean initiating, boolean resetOrigin) { if (taxaPane==null || initiating) { if (!initiating) removeFromWindow(taxaDisplay); messageWidth=baseMessageWidth; taxaPane = new TaxaScrollPane(this); taxaPane.setLocation(0, 0); hAdjust = taxaPane.getHAdjustable(); hAdjust.addAdjustmentListener(this); vAdjust = taxaPane.getVAdjustable(); vAdjust.addAdjustmentListener(this); oldH = hAdjust.getValue(); oldV = vAdjust.getValue(); taxaPane.addTaxaDisplay(taxaDisplay); addToWindow(taxaPane); sizeDisplay(resetOrigin); //taxaPane.setScrollPosition(-initPosX, -initPosY); floatLegendsItem.setEnabled(true); if (!initiating) { ownerModule.resetContainingMenuBar(); taxaPane.setVisible(true); taxaDisplay.pleaseUpdate(true); messagePanel.repaint(); } } if (resetOrigin) setOrigin(0, 0, true); } /*.................................................................................................................*/ /** Called in some circumstances (not all) when a component is added to a container in the window. Currently used so that the taxa window knows that a component has been added to the TaxaDisplay.*/ public void componentAdded(Container cont, Component comp){ checkLegendPositionsLegal(); } /*.................................................................................................................*/ public void sizeDisplay(){ if (taxaPane!=null){ } if (taxaDisplay==null ||messagePanel==null) return; scaleToFit = taxaDisplay.getScaleToFit(); if (scaleToFit) { togglePane(true, true); if (taxaPane != null) taxaPane.setSize(getWidth(), getHeight() - scrollWidth); int width = getWidth(); int height = getHeight()-scrollWidth; Dimension d = taxaDrawCoordTask.getPreferredSize(); if (d.getHeight()>0) { double mapRatio = d.getWidth()/d.getHeight(); double currentRatio = 1.0*width/height; double shrink = 1.0; if (mapRatio>currentRatio) { // then the map is relatively wider than the current window, so need to shrink to fit width int newHeight = (int)(height*(currentRatio/mapRatio)); taxaDisplay.setSize(width, newHeight); taxaDisplay.setFieldSize(width, newHeight); } else { int newWidth = (int)(width*(mapRatio/currentRatio)); taxaDisplay.setSize(newWidth, height); taxaDisplay.setFieldSize(newWidth, height); } } // taxaDrawCoordTask.get taxaDisplay.redoCalculations(8813); //togglePane(true, false); } else { // not scale to fit Dimension s = taxaDrawCoordTask.getPreferredSize(); oldPreferred = s; if (s != null) { //if taxadrawer has preferred size then put here totalTaxaFieldWidth = s.width; totalTaxaFieldHeight = s.height; toggleLegendFloat(); } else if (taxa.getNumTaxa()>50) { totalTaxaFieldWidth = taxa.getNumTaxa()*14; totalTaxaFieldHeight = taxa.getNumTaxa()*14; toggleLegendFloat(); } togglePane(true, false); if (taxaPane != null) taxaPane.setSize(getWidth(), getHeight() - scrollWidth); taxaDisplay.setFieldSize(totalTaxaFieldWidth, totalTaxaFieldHeight); int useWidth = MesquiteInteger.maximum(totalTaxaFieldWidth, getWidth()); int useHeight = MesquiteInteger.maximum(totalTaxaFieldHeight, getHeight()-scrollWidth); taxaDisplay.setSize(useWidth,useHeight); } if (usingPane) { taxaPane.setHMinMax(0, taxaDisplay.getFieldWidth() - taxaPane.getWidth() - scrollWidth); int increment = taxaPane.getHeight() / 10; if (increment>taxaDisplay.getFieldHeight()) increment = taxaDisplay.getFieldHeight(); vScroll.setBlockIncrement(increment); increment = taxaPane.getWidth() / 10; if (increment>taxaDisplay.getFieldWidth()) increment = taxaDisplay.getFieldWidth(); hScroll.setBlockIncrement(increment); vScroll.setUnitIncrement(10); hScroll.setUnitIncrement(10); resetScrolls(); taxaPane.setVMinMax(0, taxaDisplay.getFieldHeight() - taxaPane.getHeight() - scrollWidth - scrollWidth); taxaPane.doLayout(); // vScroll.doLayout(); // hScroll.doLayout(); // setOrigin(treeRect.x, treeRect.y); } else { taxaDisplay.setSize(getWidth(), getHeight() - scrollWidth); setOrigin(0, 0, true); } taxaDisplay.setVisRect(getTaxaViewport()); messageWidth = getWidth(); messagePanel.setLocation(0, getHeight()-scrollWidth); messagePanel.setSize(messageWidth,scrollWidth); checkLegendPositionsLegal(); } /*.................................................................................................................* void setSuggestedSize(boolean setToDefault, boolean togglepane){ Dimension s = taxaDrawCoordTask.getPreferredSize(); oldPreferred = s; if (!setToDefault && s != null) { //if taxadrawer has perferred size then put here totalTaxaFieldWidth = s.width; totalTaxaFieldHeight = s.height; toggleLegendFloat(); } else if (taxa.getNumTaxa()>50) { totalTaxaFieldWidth = taxa.getNumTaxa()*14; totalTaxaFieldHeight = taxa.getNumTaxa()*14; toggleLegendFloat(); } if (togglepane) togglePane(false); sizeDisplay(); } /*.................................................................................................................*/ public Taxa getTaxa() { return taxa; } /*.................................................................................................................*/ public void hideTaxa() { if (taxaDisplay!=null) taxaDisplay.setVisible(false); } /*.................................................................................................................*/ public void showTaxa() { if (taxaDisplay!=null) taxaDisplay.setVisible(true); } /*.................................................................................................................* public void setTaxaSource(TaxaSource tsTask) { boolean setToZero = tsTask != taxaSourceTask; taxaSourceTask = tsTask; resetTitle(); if (!MesquiteThread.isScripting()){ resetForTaxaSource(setToZero, true); contentsChanged(); taxaDisplay.repaint(); } else { resetForTaxaSource(setToZero, true); } } /*.................................................................................................................* public void resetForTaxaSource(boolean setToZero, boolean firstTimeTaxaSource) { if (firstTimeTaxaSource) warningGivenForTaxaSource = false; MesquiteTree editedTree = null; if (taxa !=null && taxa.isDoomed()) { ownerModule.iQuit(); return; } treeAnnotationShown = false; taxaDisplay.setTaxa(null); //done to catch spurious redraws checkLegendPositionsLegal(); resetBaseExplanation(); } /*.................................................................................................................*/ public void addAssistant(TaxaDisplayAssistant tda) { taxaDrawCoordTask.addAssistantTask(tda); TaxaDisplayExtra tce = tda.createTaxaDisplayExtra(taxaDisplay); if (tce==null) return; tce.setTaxa(taxa); taxaDisplay.addExtra(tce); checkLegendPositionsLegal(); taxaDisplay.pleaseUpdate(false); if (getMode()>0) updateTextPage(); } void fileReadIn(){ sizeDisplay(); } /*.................................................................................................................*/ public Snapshot getSnapshot(MesquiteFile file) { Snapshot temp = new Snapshot(); temp.addLine("getTaxaDrawCoordinator", taxaDrawCoordTask); temp.incorporate(super.getSnapshot(file), false); return temp; } /** Returns menu location for item to bring the window to the for (0 = custom or don't show; 1 = system area of Windows menu; 2 = after system area of Windows menu)*/ public int getShowMenuLocation(){ return 0; } /*.................................................................................................................*/ public String getPrintMenuItem() { return "Print Taxa..."; } /*.................................................................................................................*/ public String getPrintToFitMenuItemName() { return "Print Taxa To Fit Page..."; } /* ................................................................................................................. */ public void windowToPDF(MesquitePDFFile pdfFile, int fitToPage) { if (pdfFile != null) { if (infoBar.getMode() > 0) super.windowToPDF(pdfFile, fitToPage); else { Dimension oldtaxaDisplaySize = taxaDisplay.getSize(); taxaDisplay.setPrintingInProcess(true); taxaDisplay.setSize(taxaDisplay.getFieldWidth(), taxaDisplay.getFieldHeight()); //Rectangle r = taxaDisplay.getVisRect(); //taxaDisplay.setVisRect(null); Graphics g2 = pdfFile.getPDFGraphicsForComponent(taxaDisplay, null); taxaDisplay.printAll(g2); taxaDisplay.setSize(oldtaxaDisplaySize.width, oldtaxaDisplaySize.height); //taxaDisplay.setVisRect(r); taxaDisplay.setPrintingInProcess(false); taxaDisplay.repaintAll(); pdfFile.end(); } } } /* ................................................................................................................. */ public String getPrintToPDFMenuItemName() { return "Save Map as PDF..."; } protected void pdfWindow(int fitToPage) { super.pdfWindow(fitToPage); } /*.................................................................................................................*/ public void printWindow(MesquitePrintJob pjob) { if (pjob != null) { if (infoBar.getMode()>0) super.printWindow(pjob); else pjob.printComponent(taxaDisplay, null, null); } } /*.................................................................................................................*/ public void setCurrentTool(MesquiteTool tool){ if (tool!=null && !tool.getEnabled()) return; if (tool instanceof TaxaTool) currentTaxaTool = (TaxaTool)tool; super.setCurrentTool(tool); } /*...............................................................................................................*/ protected void setContentsCursor(Cursor c){ if (c == null) MesquiteMessage.printStackTrace("Error: cursor of taxa window null"); else if (taxaDisplay !=null) taxaDisplay.setCursor(c); } public void setRescaleValue(double rescaleValue) { ListableVector ev = taxaDisplay.getExtras(); taxaDisplay.setRescaleValue(rescaleValue); for (int i=0; i< ev.size(); i++){ TaxaDisplayExtra extra = (TaxaDisplayExtra)ev.elementAt(i); if (extra!=null ) { extra.setRescaleValue(rescaleValue); } } } public void contentsChanged() { if (taxaDrawCoordTask!=null) { double rescaleValue = taxaDrawCoordTask.getRescaleValue(); setRescaleValue(rescaleValue); } super.contentsChanged(); } /*.................................................................................................................*/ MesquiteInteger pos = new MesquiteInteger(); /*.................................................................................................................*/ public Object doCommand(String commandName, String arguments, CommandChecker checker) { if (checker.compare(this.getClass(), "Hires a taxa display assistant module", "[name of assistant module]", commandName, "newAssistant")) { ownerModule.incrementMenuResetSuppression(); TaxaDisplayAssistant tda= (TaxaDisplayAssistant)ownerModule.hireNamedEmployee(TaxaDisplayAssistant.class, arguments); if (tda!=null) { addAssistant(tda); if (!MesquiteThread.isScripting()) ownerModule.resetContainingMenuBar(); } ownerModule.decrementMenuResetSuppression(); return tda; } else if (checker.compare(this.getClass(), "Returns the taxa draw coordinating module", null, commandName, "getTaxaDrawCoordinator")) { return taxaDrawCoordTask; } else if (checker.compare(this.getClass(), "Hires a taxa window assistant module", "[name of assistant module]", commandName, "newWindowAssistant")) { TaxaWindowAssistant tda= (TaxaWindowAssistant)ownerModule.hireNamedEmployee(TaxaWindowAssistant.class, arguments); if (tda!=null) tda.setTaxa(taxa); return tda; } else if (checker.compare(this.getClass(), "Brings the graphics of an assistant module to the front", "[number of assistant module among TaxaDisplayDrawnExtra owners]", commandName, "bringToFront")) { int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; ListableVector ev = taxaDisplay.getExtras(); int count =0; for (int i=0; i< ev.size(); i++){ TaxaDisplayExtra extra = (TaxaDisplayExtra)ev.elementAt(i); if (extra!=null && extra instanceof TaxaDisplayDrawnExtra) { if (count== which) { TaxaDisplayExtra found = extra; ownerModule.moveEmployeeToFront(extra.getOwnerModule()); taxaDisplay.moveExtraToFront(extra); ownerModule.resetContainingMenuBar(); return null; } count++; } } } else if (checker.compare(this.getClass(), "Closes an assistant module", "[number of assistant module]", commandName, "closeDisplayAssistant")) { EmployeeVector ev = ownerModule.getEmployeeVector(); int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; int count =0; for (int i=0; i< ev.size(); i++){ MesquiteModule mb = (MesquiteModule)ev.elementAt(i); if (mb!=null && mb instanceof TaxaDisplayAssistantAD) { if (count== which) { ownerModule.fireEmployee(mb); return null; } count++; } } } else if (checker.compare(this.getClass(), "Saves a macro to redo the analysis of an assistant module", "[number of assistant module]", commandName, "saveMacroDisplayAssistant")) { EmployeeVector ev = ownerModule.getEmployeeVector(); int which = MesquiteInteger.fromFirstToken(arguments, pos); if (!MesquiteInteger.isCombinable(which)) return null; int count =0; for (int i=0; i< ev.size(); i++){ MesquiteModule mb = (MesquiteModule)ev.elementAt(i); if (mb!=null && mb instanceof TaxaDisplayAssistantAD) { if (count== which) { String recipe = "newAssistant #" + mb.getClass().getName() + ";" + StringUtil.lineEnding() + "tell It;"+ StringUtil.lineEnding(); recipe += Snapshot.getSnapshotCommands(mb, null, ""); recipe += "endTell;"+ StringUtil.lineEnding(); MesquiteMacro.saveMacro(ownerModule, "Macro to start " + mb.getNameForMenuItem(), 0, recipe); return null; } count++; } } } else if (checker.compare(this.getClass(), "Requests that the taxa are drawn to a default (suggested) size", null, commandName, "useSuggestedSize")) { //absorbs old scripts } else if (checker.compare(this.getClass(), "Sets whether or not the taxa is drawn so as to fit within the window, or so as to fit within a scrollable pane", "[on or off to indicate whether constrained to window]", commandName, "toggleSizeToFit")) { //absorbs old scripts } else if (checker.compare(this.getClass(), "When Size to Window is false, brings legends into view", null, commandName, "toggleLegendFloat")) { boolean current = floatLegends.getValue(); pos.setValue(0); floatLegends.toggleValue(ParseUtil.getFirstToken(arguments, pos)); if (current != floatLegends.getValue()) toggleLegendFloat(); else checkLegendPositionsLegal(); } else if (checker.compare(this.getClass(), "Sets the size of the drawing pane area (only useful if Size To Fit is turned off)", "[width in pixels of drawing area] [height in pixels of drawing area]", commandName, "sizeDrawing")) { pos.setValue(0); int w = MesquiteInteger.fromString(arguments, pos); int h = MesquiteInteger.fromString(arguments, pos); if (MesquiteInteger.isCombinable(h) && MesquiteInteger.isCombinable(w)) { if (w>10 && h>10) { totalTaxaFieldWidth = w; totalTaxaFieldHeight = h; sizeDisplay(); } } else { MesquiteBoolean answer = new MesquiteBoolean(false); MesquiteInteger newWidth = new MesquiteInteger(totalTaxaFieldWidth); MesquiteInteger newHeight =new MesquiteInteger(totalTaxaFieldHeight); MesquiteInteger.queryTwoIntegers(ownerModule.containerOfModule(), "Size of taxa drawing", "Width (Pixels)", "Height (Pixels)", answer, newWidth, newHeight,10,MesquiteInteger.unassigned,10, MesquiteInteger.unassigned,"Enter the width and height of the taxa drawing. These values must be at least 10 pixels each."); if (answer.getValue() && newWidth.getValue()>10 && newHeight.getValue()>10) { totalTaxaFieldWidth = newWidth.getValue(); totalTaxaFieldHeight = newHeight.getValue(); sizeDisplay(); } } } else if (checker.compare(this.getClass(), "Sets size of taxa window", "[width in pixels of window] [height in pixels of window]", commandName, "setSize")) { MesquiteInteger io = new MesquiteInteger(0); int width= MesquiteInteger.fromString(arguments, io); int height= MesquiteInteger.fromString(arguments, io); if (MesquiteInteger.isCombinable(width) && MesquiteInteger.isCombinable(height)) { fromScriptCommand = true;//this is needed to counteract difficulties with popping in/out and size setting in window constructors setWindowSize(width, height); fromScriptCommand = false; sizeDisplay(); } } else if (checker.compare(this.getClass(), "Sets the origin for the scrolling area", "[origin x] [origin y]", commandName, "setOrigin")) { pos.setValue(0); int horiz = MesquiteInteger.fromString(arguments, pos); int vert = MesquiteInteger.fromString(arguments, pos); if (MesquiteInteger.isCombinable(horiz) && MesquiteInteger.isCombinable(vert)) { setOrigin(horiz, vert, true); } } else if (checker.compare(this.getClass(), "Sets the current tool", "[name of tool]", commandName, "setTool")) { ToolPalette palette = getPalette(); if (palette ==null) return null; currentTaxaTool = (TaxaTool)palette.getToolWithName(arguments); setCurrentTool(currentTaxaTool); setExplanation(currentTaxaTool.getDescription()); } /* else if (checker.compare(this.getClass(), "Zoom image", "[x][y]", commandName, "zoom")) { int x= MesquiteInteger.fromFirstToken(arguments, pos); int y= MesquiteInteger.fromString(arguments, pos); boolean zoomIn = (arguments.indexOf("option")<0); zoom(x,y, zoomIn); }*/ else return super.doCommand(commandName, arguments, checker); return null; } /*.................................................................................................................*/ void zoom(int x, int y, boolean zoomIn){ /* boolean current = sizeToFit.getValue(); int oX = getOriginX(); int oY = getOriginY(); useSuggestedSize.setValue(false); int tW, tH; if (current){ tW = taxaDisplay.getBounds().width; tH = taxaDisplay.getBounds().height; } else { tW = totalTaxaFieldWidth; tH = totalTaxaFieldHeight; } pos.setValue(0); if (current) sizeToFit.setValue(false); int newWidth, newHeight; if (zoomIn){ newWidth = tW*2; newHeight = tH*2; } else { newWidth = tW/2; newHeight = tH/2; } totalTaxaFieldWidth = newWidth; totalTaxaFieldHeight = newHeight; sizeDisplay(); togglePane(false, false); int setX, setY; if (zoomIn) { setX = oX-x; setY = oY-y +scrollWidth; //why is this needed? } else { setX = oX+x/2; setY = oY+y/2; } /* if (zoomIn) setOrigin(-(x+ 2*oX),-(y+2*oY)); else setOrigin(-(oX-x)/2,-(oY-y)/2); setOrigin(setX, setY); //taxaDisplay.getTaxaDrawing().recalculatePositions(taxaDisplay.getTree()); //to force node locs recalc*/ } /*.................................................................................................................*/ public String getTextContents() { if (taxaDisplay==null) return ""; String s = "Taxa window\n"; //if (taxaSourceTask !=null) // s += "Showing " + taxaSourceTask.getNameForMenuItem(); if (taxa!=null) s += " for taxa \"" + taxa.getName() + "\""; s += "\n\n" + taxaDisplay.getTextVersion(); return s; } /*.................................................................................................................*/ public void paintContents(Graphics g) { if (taxaDisplay==null) { MesquiteMessage.warnProgrammer("Oh no, taxa display is null"); } else { //^^^ sizeDisplay(); taxaDisplay.repaint(); checkLegendPositionsLegal(); g.setColor(Color.black); } } //for java 1.1 printing public Object fit(Dimension dim){ Dimension d = new Dimension(getOriginX(), getOriginY()); taxaDisplay.setFieldSize(dim.width,dim.height); setOrigin(0,0, true); taxaDisplay.getTaxaDrawing().recalculatePositions(taxa); //to force node locs recalc return d; } public void unfit(Object o){ int oX = 0; int oY = 0; if (o instanceof Dimension) { oX = ((Dimension)o).width; oY = ((Dimension)o).height; } setOrigin(oX,oY, true); sizeDisplay(); } public int getOriginX() { if (!usingPane) return 0; Point p = getTaxaScrollPoint(); return p.x; // Adjustable h = taxaPane.getHAdjustable(); // return -(int)( ((1.0*(h.getValue()- h.getMinimum()))/(h.getMaximum()-h.getMinimum()))*taxaDisplay.getBounds().width); } public int getOriginY() { if (!usingPane) return 0; Point p = getTaxaScrollPoint(); return p.y; // Adjustable v = taxaPane.getVAdjustable(); // return -(int)( ((1.0*(v.getValue()- v.getMinimum()))/(v.getMaximum()-v.getMinimum()))*taxaDisplay.getBounds().height); } /* public int getOriginX() { if (taxaPane ==null) return 0; Adjustable h = taxaPane.getHAdjustable(); return -(int)( ((1.0*(h.getValue()- h.getMinimum()))/(h.getMaximum()-h.getMinimum()))*taxaDisplay.getBounds().width); } public int getOriginY() { if (taxaPane ==null) return 0; Adjustable v = taxaPane.getVAdjustable(); return -(int)( ((1.0*(v.getValue()- v.getMinimum()))/(v.getMaximum()-v.getMinimum()))*taxaDisplay.getBounds().height); } */ /*_________________________________________________*/ public void InvertTaxa(Graphics g, int M) { if (findTaxon(taxaDisplay.getMouseX(), taxaDisplay.getMouseY()) == M){ //still in taxa g.setColor(Color.black); g.setXORMode(Color.white); taxaDisplay.fillTaxon(g, M); g.setPaintMode(); g.setColor(Color.black); highlightedTaxa=M; } Taxa t = taxaDisplay.getTaxa(); if (t !=null) { if (t.getAnnotation(M)!=null) setAnnotation(t.getAnnotation(M), "Annotation above refers to taxa \"" + t.getTaxonName(M) + "\""); else setExplanation("Taxon: " + t.getTaxonName(M)); } } /*_________________________________________________*/ public void RevertTaxa(Graphics g, int M) { if (highlightedTaxa >= 0){ g.setColor(Color.black); g.setXORMode(Color.white); taxaDisplay.fillTaxon(g, highlightedTaxa); g.setPaintMode(); highlightedTaxa=-1; g.setColor(Color.black); } setAnnotation("", null); } /*_________________________________________________*/ private int getTaxonSymbolNearLocation(int x, int y){ for (int it=0; it= 0) { if (taxonFound==-1) { notifyExtrasOfTaxaExit(g, highlightedTaxa); RevertTaxa(g, highlightedTaxa); setExplanation(baseExplanation, false); //revert explanation to default one } else if (taxonFound!=highlightedTaxa) { notifyExtrasOfTaxaExit(g, highlightedTaxa); RevertTaxa(g, highlightedTaxa); notifyExtrasOfTaxaEnter(g, taxonFound); InvertTaxa(g, taxonFound); } else currentTaxaTool.taxonMoveOver(taxonFound, modifiers); } else if (taxonFound!=-1 && !currentTaxaTool.getIgnoreTaxa()) { currentTaxaTool.taxonMoveOver(taxonFound, modifiers); notifyExtrasOfTaxaEnter(g, taxonFound); InvertTaxa(g, taxonFound); } else { currentTaxaTool.moved(x,y,modifiers); //notify extras? } } int oldX=MesquiteInteger.unassigned; int oldY=MesquiteInteger.unassigned; int newX=MesquiteInteger.unassigned; int newY=MesquiteInteger.unassigned; static final int dotSize = 8; /*.................................................................................................................*/ public void firstDot(Graphics g) { Composite composite = ColorDistribution.getComposite(g); ColorDistribution.setTransparentGraphics(g); if (MesquiteInteger.isCombinable(oldX) && MesquiteInteger.isCombinable(oldY)){ //erase old one g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2,false); } g.setPaintMode(); g.setColor(Color.black); ColorDistribution.setComposite(g,composite); } /*.................................................................................................................*/ public void moveDot(Graphics g) { Composite composite = ColorDistribution.getComposite(g); ColorDistribution.setTransparentGraphics(g); if (MesquiteInteger.isCombinable(oldX) && MesquiteInteger.isCombinable(oldY)){ //erase old one g.setXORMode(Color.gray); // g.setColor(Color.black); // g.drawOval(oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2); g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,oldX-dotSize, oldY-dotSize, dotSize*2, dotSize*2,false); } if (MesquiteInteger.isCombinable(newX) && MesquiteInteger.isCombinable(newY)){ //erase old one g.setXORMode(Color.gray); // g.setColor(Color.black); // g.drawOval(newX-dotSize, newY-dotSize, dotSize*2, dotSize*2); g.setColor(Color.darkGray); GraphicsUtil.fillOval(g,newX-dotSize, newY-dotSize, dotSize*2, dotSize*2,false); } g.setPaintMode(); g.setColor(Color.black); ColorDistribution.setComposite(g,composite); } /*.................................................................................................................*/ int taxonTouched = MesquiteInteger.unassigned; /*_________________________________________________*/ public void ScanDrop(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxaDrawCoordTask == null || taxaDrawCoordTask.getNamesTask() == null || taxaDisplay.getTaxaDrawing()==null) return; if (taxaDisplay.getInvalid()) return; xFrom = -1; yFrom = -1; xTo = -1; yTo = -1; int nameFound = findTaxon(x,y); if (MesquiteInteger.isCombinable(taxonTouched)){ newX=MesquiteInteger.unassigned; newY=MesquiteInteger.unassigned; moveDot(g); currentTaxaTool.taxonMouseUp(taxonTouched, x,y,modifiers); } else if (nameFound==-1 || currentTaxaTool.getIgnoreTaxa()) { boolean fieldMouseUpAccepted = currentTaxaTool.fieldMouseUp(x,y,modifiers); } //return false; } /*_________________________________________________*/ public boolean ScanTouch(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxaDrawCoordTask == null || taxaDrawCoordTask.getNamesTask() == null || taxaDisplay.getTaxaDrawing()==null) return false; if (taxaDisplay.getInvalid()) return false; xFrom = -1; yFrom = -1; xTo = -1; yTo = -1; oldX=MesquiteInteger.unassigned; oldY=MesquiteInteger.unassigned; newX=MesquiteInteger.unassigned; newY=MesquiteInteger.unassigned; taxonTouched = MesquiteInteger.unassigned; int nameFound = findTaxon(x,y); if (nameFound!=-1 && !currentTaxaTool.getIgnoreTaxa()) { currentTaxaTool.taxonTouched(nameFound, modifiers); notifyExtrasOfTaxaTouch(g, nameFound); if (highlightedTaxa >= 0 ) RevertTaxa(g, highlightedTaxa); taxonTouched = nameFound; //oldX = x; //oldY = y; //firstDot(g); return true; } else { boolean fieldTouchAccepted=true; fieldTouchAccepted = currentTaxaTool.fieldTouched(x,y,modifiers); //notify extras? return fieldTouchAccepted; } //return false; } /*_________________________________________________*/ public void ScanDrag(Graphics g, int x, int y, int modifiers) { if (taxaDisplay == null || taxa == null) return; if (taxaDisplay.getInvalid()) return; if (MesquiteInteger.isCombinable(taxonTouched)) { newX = x; newY = y; moveDot(g); oldX = x; oldY = y; currentTaxaTool.taxonDragged(taxonTouched,x,y,modifiers); } // fill out DRM: } /*................................................................................................*/ public void notifyExtrasOfTaxaEnter(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorEnterTaxon(M, g); } } } } /*................................................................................................*/ public void notifyExtrasOfTaxaExit(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorExitTaxon( M, g); } } } } /*................................................................................................*/ public void notifyExtrasOfTaxaTouch(Graphics g, int M) { if (taxaDisplay.getExtras()!=null) { Enumeration e = taxaDisplay.getExtras().elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TaxaDisplayExtra) { TaxaDisplayExtra tce = (TaxaDisplayExtra)obj; tce.cursorTouchTaxon(M, g); } } } } /*.................................................................................................................*/ /** passes which object is being disposed (from MesquiteListener interface)*/ public void disposing(Object obj){ if (obj instanceof Taxa && (Taxa)obj ==taxa) { ownerModule.iQuit(); } } /*.................................................................................................................*/ /** passes which object is being disposed (from MesquiteListener interface)*/ public boolean okToDispose(Object obj, int queryUser){ return true; //TODO: respond } /*.................................................................................................................*/ /** passes which object changed (from MesquiteListener interface)*/ public void changed(Object caller, Object obj, Notification notification){ int code = Notification.getCode(notification); int[] parameters = Notification.getParameters(notification); if (obj instanceof Taxa && (Taxa)obj ==taxa) { if (code==MesquiteListener.TAXA_DRAWING_SIZING_CHANGED) { windowResized(); canUndo = false; taxaDisplay.pleaseUpdate(true); } else if (code==MesquiteListener.PARTS_CHANGED || code ==MesquiteListener.PARTS_ADDED || code == MesquiteListener.PARTS_MOVED || code == MesquiteListener.PARTS_DELETED) { canUndo = false; taxaDisplay.pleaseUpdate(true); } else if (code==MesquiteListener.NAMES_CHANGED || code == MesquiteListener.SELECTION_CHANGED || code == AssociableWithSpecs.SPECSSET_CHANGED) taxaDisplay.pleaseUpdate(true); if (getMode()>0) updateTextPage(); } super.changed(caller, obj, notification); } /*.................................................................................................................*/ void resetBaseExplanation(){ String td = ""; String td2 = ""; if (ownerModule.getProject().getNumberTaxas()>1) td += "Taxa window shows taxa \"" + taxa.getName() + "\"\n"; baseExplanation.setValue(td + "Browsing Mode. " + td2 + "The taxa shown are from " + taxa.getName()); setExplanation(baseExplanation, true); } /*.................................................................................................................*/ public void setExplanation(String exp){ baseExplanationUsed = false; super.setExplanation(exp); } /*.................................................................................................................*/ void setExplanation(MesquiteString exp, boolean setEvenIfAlreadyBase){ if (exp == null) return; if (exp != baseExplanation || !(baseExplanationUsed && !setEvenIfAlreadyBase)) { baseExplanationUsed = true; super.setExplanation(exp.toString()); } } /* ................................................................................................................. */ public void windowResized() { super.windowResized(); if (!MesquiteThread.isScripting() || (windowModule != null && windowModule.respondToWindowResize)) sizeDisplay(); if (taxaDrawCoordTask!=null) { taxaDrawCoordTask.setRescaleValue(); double rescaleValue = taxaDrawCoordTask.getRescaleValue(); setRescaleValue(rescaleValue); } } /*.................................................................................................................*/ public void dispose(){ disposing = true; waitUntilDisposable(); if (taxa!=null) taxa.removeListener(this); windowModule = null; if (currentTaxaTool!=null) { currentTaxaTool.dispose(); currentTaxaTool = null; } taxaDrawCoordTask = null; // taxaSourceTask = null; if (taxaDisplay !=null){ removeFromWindow(taxaDisplay); taxaDisplay.dispose(); } taxaDisplay=null; //if (rooted!=null) // rooted.releaseMenuItem(); super.dispose(); } } /* ======================================================================== */ class REALTaxaScrollPane extends ScrollPane{ BasicTaxaWindow window; public REALTaxaScrollPane (int scrollPolicy, BasicTaxaWindow window) { super(scrollPolicy); this.window = window; } public void addTaxaDisplay(Component c){ addImpl(c, null, 0); } public void setSize(int w, int h){ super.setSize(w, h); window.checkLegendPositionsLegal(); } public void setScrollPosition(int x, int y) { super.setScrollPosition(x,y); } public void setScrollPosition(Point p) { super.setScrollPosition(p); } public void setBounds(int x, int y, int w, int h){ super.setBounds(x, y, w, h); window.checkLegendPositionsLegal(); } } /* ======================================================================== */ /* * this is an attempt to get around the bug in OS X java 1.4+ in which ScrollPane scrollbars don't return their position and don't notify of adjustments. This faux-ScrollPane works reasonably well but is slower and has some graphical artifacts */ class TaxaScrollPane extends Panel implements MouseWheelListener { // HANDMADETreeScrollPane BasicTaxaWindow window; TaxaScroll hScroll, vScroll; Panel port; Component taxaDisplay; public TaxaScrollPane(BasicTaxaWindow window) { super(); hScroll = new TaxaScroll(this, Scrollbar.HORIZONTAL, 0, 2, 0, 0); vScroll = new TaxaScroll(this, Scrollbar.VERTICAL, 0, 2, 0, 0); setLayout(new BorderLayout()); add(hScroll, BorderLayout.SOUTH); add(vScroll, BorderLayout.EAST); add(port = new Panel(), BorderLayout.CENTER); addMouseWheelListener(this); port.setLayout(null); doLayout(); this.window = window; } public void addTaxaDisplay(Component c) { port.add(c); taxaDisplay = c; } public boolean isFauxScrollPane() { return true; } public Adjustable getHAdjustable() { return hScroll; } public Adjustable getVAdjustable() { return vScroll; } public void setHMinMax(int min, int max) { if (min < 0) min = 0; if (max < min) max = min; boolean touch = hScroll.setMinimumWithResetWarning(min); touch = hScroll.setMaximumWithResetWarning(max) || touch; if (touch) scrollTouched(null, 0); hScroll.setVisible(min != max); if (min == max) taxaDisplay.setLocation(0, taxaDisplay.getLocation().y); } public void setVMinMax(int min, int max) { if (min < 0) min = 0; if (max < min) max = min; boolean touch = vScroll.setMinimumWithResetWarning(min); touch = vScroll.setMaximumWithResetWarning(max) || touch; if (touch) scrollTouched(null, 0); vScroll.setVisible(min != max); if (min == max) taxaDisplay.setLocation(taxaDisplay.getLocation().x, 0); } public void scrollTouched(TaxaScroll scroll, int value) { window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); constrainTaxaDisplay(); } public Dimension getViewportSize() { return new Dimension(port.getWidth(), port.getHeight()); } public int getContentsWidth() { return port.getWidth(); } public int getContentsHeight() { return port.getHeight(); } public Point getScrollPosition() { return new Point(hScroll.getValue(), vScroll.getValue()); } public void setScrollPosition(int h, int v) { hScroll.setValue(h); vScroll.setValue(v); } public void constrainTaxaDisplay() { // post 2. 6 needed at least for OS X as workaround for JVM failure to respect bounds of containing panel if (taxaDisplay == null) return; int w = port.getWidth(); int h = port.getHeight(); int wReduce = 0; int hReduce = 0; if (taxaDisplay.getWidth() + taxaDisplay.getX() != w) wReduce = taxaDisplay.getWidth() + taxaDisplay.getX() - w; if (taxaDisplay.getHeight() + taxaDisplay.getY() != h) hReduce = taxaDisplay.getHeight() + taxaDisplay.getY() - h; if (wReduce != 0 || hReduce != 0) taxaDisplay.setSize(taxaDisplay.getWidth() - wReduce, taxaDisplay.getHeight() - hReduce); } public void setSize(int w, int h) { super.setSize(w, h); doLayout(); constrainTaxaDisplay(); window.checkPanelPositionsLegal(); } public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); doLayout(); constrainTaxaDisplay(); window.checkPanelPositionsLegal(); } public void mouseWheelMoved(MouseWheelEvent e) { int amount = e.getScrollAmount() * 2; boolean blockScroll = e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL; boolean vert = !e.isShiftDown(); boolean upleft = e.getWheelRotation() < 0; if (vert) { if (blockScroll) amount = vScroll.getBlockIncrement(); else amount = vScroll.getUnitIncrement() * amount; if (upleft) { amount = -amount; if (vScroll.getValue() == 0) amount = 0; } if (amount != 0) { vScroll.setValue(vScroll.getValue() + amount); //window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); window.sizeDisplay(); } } else { if (blockScroll) amount = hScroll.getBlockIncrement(); else amount = hScroll.getUnitIncrement() * amount; if (upleft) { amount = -amount; if (hScroll.getValue() == 0) amount = 0; } if (amount!=0) { hScroll.setValue(hScroll.getValue()); //window.setOrigin(hScroll.getValue(), vScroll.getValue(), false); window.sizeDisplay(); } } } } /* ======================================================================== * class LockPanel extends MousePanel { Image lockClosed, lockOpen, lockImage; BasicTaxaWindow window; int state; public LockPanel(BasicTaxaWindow window){ super(); this.window = window; lockClosed = MesquiteImage.getImage(MesquiteModule.getRootPath() + "images/lockClosed.gif"); lockOpen = MesquiteImage.getImage(MesquiteModule.getRootPath() + "images/lockOpen.gif"); setLockState(0); } public void setLockState(int state){ this.state = state; if (state == 0) lockImage = lockClosed; else if (state ==1) lockImage = lockClosed; else if (state == 2) lockImage = lockOpen; } public void paint(Graphics g) { //^^^ if (MesquiteWindow.checkDoomed(this)) return; g.drawImage(lockImage, 0, -1, this); g.drawLine(0, getBounds().height-1, getBounds().width, getBounds().height-1); MesquiteWindow.uncheckDoomed(this); } public void mouseUp(int modifiers, int x, int y, MesquiteTool tool) { window.lockTouched(); repaint(); } } */ /* ======================================================================== */ class MessagePanel extends Panel { String message; MesquiteModule ownerModule; boolean showDiamond = false; boolean indicateModified; String modifiedString = ""; Polygon poly; int left = 4; int top = 4; int s = 8; public MessagePanel(MesquiteModule ownerModule) { //in future pass general MesquiteWindow super(); message=""; poly = new Polygon(); poly.xpoints = new int[4]; poly.ypoints = new int[4]; poly.npoints=0; poly.addPoint(left, top+s/2); poly.addPoint(left + s/2, top); poly.addPoint(left + s, top+s/2); poly.addPoint(left + s/2, top+s); poly.npoints=4; this.ownerModule = ownerModule; setBackground(ColorTheme.getInterfaceElement()); } public void paint(Graphics g) { if (MesquiteWindow.checkDoomed(this)) return; g.drawRect(0,0, getBounds().width -1, getBounds().height-1); if (showDiamond){ g.fillPolygon(poly); if (message != null) g.drawString(modifiedString + message, left + s + 4, 12); } else if (message != null) g.drawString(modifiedString + message, 4, 12); MesquiteWindow.uncheckDoomed(this); } public void setMessage(String s) { message = s; repaint(); } public void setHighlighted(boolean showDiamond, boolean showGreen, boolean indicateModified) { this.showDiamond = showDiamond; if (indicateModified) modifiedString ="Modified from "; else modifiedString = ""; if (showGreen) setBackground(ColorDistribution.lightGreen); else setBackground(ColorTheme.getInterfaceElement()); repaint(); } } /* ======================================================================== */ /* scrollbar for taxa */ class TaxaScroll extends MesquiteScrollbar { TaxaScrollPane tsp; public TaxaScroll (TaxaScrollPane tsp, int orientation, int value, int visible, int min, int max){ super(orientation, value, visible, min, max); this.tsp = tsp; } public boolean setMinimumWithResetWarning(int m) { boolean resetNeeded = false; if (getValue() < m) { setValue(m); resetNeeded = true; } super.setMinimum(m); return resetNeeded; } public boolean setMaximumWithResetWarning(int m) { boolean resetNeeded = false; if (getValue() > m) { setValue(m); resetNeeded = true; } super.setMaximum(m); return resetNeeded; } public void scrollTouched() { int currentValue = getValue(); tsp.scrollTouched(this, currentValue); } public boolean processDuringAdjustment() { return true; } public void print(Graphics g) { } } /* ======================================================================== * class MagnifyExtra extends TaxaDisplayExtra { Image image; public MagnifyExtra (MesquiteModule ownerModule, TaxaDisplay taxaDisplay, TaxaTool tool) { super(ownerModule, taxaDisplay); image = MesquiteImage.getImage(tool.getImagePath()); } /*.................................................................................................................* public void drawOntaxa(Tree tree, int drawnRoot, Graphics g) { if (drawnRoot!= tree.getRoot()) { TaxaDrawing td = taxaDisplay.getTaxaDrawing(); g.drawImage(image, td.x[drawnRoot], td.y[drawnRoot], taxaDisplay); } } public void setTree(Tree tree) { } /** Returns any strings to be appended to taxa name.* public String getTaxaStringAddition(Taxa taxa){ Taxa taxa = taxa.getTaxa(); int which = taxa.whichTaxaNumber(taxa); String s = taxa.getAnnotation(which); if (!StringUtil.blank(s)) return "*"; return null; } public void printOnTree(Tree tree, int drawnRoot, Graphics g) { } } */ \ No newline at end of file diff --git a/Source/mesquite/cartographer/aCartographerIntro/aCartographerIntro.java b/Source/mesquite/cartographer/aCartographerIntro/aCartographerIntro.java index f54990a..5beabeb 100644 --- a/Source/mesquite/cartographer/aCartographerIntro/aCartographerIntro.java +++ b/Source/mesquite/cartographer/aCartographerIntro/aCartographerIntro.java @@ -1 +1 @@ -/* Mesquite.cartographer source code. Copyright 2008-2009 D. Maddison and W. Maddison. Version 1.3, June 2008. Disclaimer: The Mesquite source code is lengthy and we are few. There are no doubt inefficiencies and goofs in this code. The commenting leaves much to be desired. Please approach this source code with the spirit of helping out. Perhaps with your help we can be more than a few, and make Mesquite better. Mesquite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Mesquite's web site is http://mesquiteproject.org This source code and its compiled class files are free and modifiable under the terms of GNU Lesser General Public License. (http://www.gnu.org/copyleft/lesser.html) */ package mesquite.cartographer.aCartographerIntro; import mesquite.lib.MesquiteTrunk; import mesquite.lib.duties.*; /* ======================================================================== */ public class aCartographerIntro extends PackageIntro { /*.................................................................................................................*/ public boolean startJob(String arguments, Object condition, boolean hiredByName) { return true; } public Class getDutyClass(){ return aCartographerIntro.class; } /*.................................................................................................................*/ public String getExplanation() { return "Cartographer is a package of Mesquite modules providing tools for plotting data in geographic space."; } /*.................................................................................................................*/ public String getName() { return "Cartographer Package"; } /*.................................................................................................................*/ /** Returns the name of the package of modules (e.g., "Basic Mesquite Package", "Rhetenor")*/ public String getPackageName(){ return "Cartographer Package"; } /*.................................................................................................................*/ /** Returns citation for a package of modules*/ public String getPackageCitation(){ return "Maddison, D.R., & W.P. Maddison. 2017. Cartographer: A Mesquite package for plotting geographic data. Version " + getPackageVersion() +" http://mesquiteproject.org/packages/cartographer"; } /*.................................................................................................................*/ /** Returns whether there is a splash banner*/ public boolean hasSplash(){ return true; } /*.................................................................................................................*/ /** returns the URL of the notices file for this module so that it can phone home and check for messages */ /*.................................................................................................................*/ public String getHomePhoneNumber(){ if (MesquiteTrunk.debugMode) return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/development/noticesAndUpdates/noticesDev.xml"; else if (!isPrerelease()) return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/master/noticesAndUpdates/notices.xml"; else return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/development/noticesAndUpdates/noticesPrerelease.xml"; } /*.................................................................................................................*/ public String getPackageURL(){ return "http://mesquiteproject.org/packages/cartographer"; } /*.................................................................................................................*/ /** Returns version for a package of modules*/ public String getPackageVersion(){ return "1.50"; } /*.................................................................................................................*/ /** Returns version for a package of modules as an integer*/ public int getPackageVersionInt(){ return 150; } public String getPackageDateReleased(){ return "1 January 2017"; } /*.................................................................................................................*/ /** Returns build number for a package of modules as an integer*/ public int getPackageBuildNumber(){ return 30; } /* release dates: v1.0 5 May 2006 v1.2 19 September 2007 v1.3 8 June 2008 v1.31 1 January 2009 v1.4 19 August 2014 v1.41 29 August 2014 v1.50 1 January 2017 (build 30) * */ /*.................................................................................................................*/ public int getVersionOfFirstRelease(){ return 260; } } \ No newline at end of file +/* Mesquite.cartographer source code. Copyright 2008-2009 D. Maddison and W. Maddison. Version 1.3, June 2008. Disclaimer: The Mesquite source code is lengthy and we are few. There are no doubt inefficiencies and goofs in this code. The commenting leaves much to be desired. Please approach this source code with the spirit of helping out. Perhaps with your help we can be more than a few, and make Mesquite better. Mesquite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Mesquite's web site is http://mesquiteproject.org This source code and its compiled class files are free and modifiable under the terms of GNU Lesser General Public License. (http://www.gnu.org/copyleft/lesser.html) */ package mesquite.cartographer.aCartographerIntro; import mesquite.lib.MesquiteTrunk; import mesquite.lib.duties.*; /* ======================================================================== */ public class aCartographerIntro extends PackageIntro { /*.................................................................................................................*/ public boolean startJob(String arguments, Object condition, boolean hiredByName) { return true; } public Class getDutyClass(){ return aCartographerIntro.class; } /*.................................................................................................................*/ public String getExplanation() { return "Cartographer is a package of Mesquite modules providing tools for plotting data in geographic space."; } /*.................................................................................................................*/ public String getName() { return "Cartographer Package"; } /*.................................................................................................................*/ /** Returns the name of the package of modules (e.g., "Basic Mesquite Package", "Rhetenor")*/ public String getPackageName(){ return "Cartographer Package"; } /*.................................................................................................................*/ /** Returns citation for a package of modules*/ public String getPackageCitation(){ return "Maddison, D.R., & W.P. Maddison. 2017. Cartographer: A Mesquite package for plotting geographic data. Version " + getPackageVersion() +" http://mesquiteproject.org/packages/cartographer"; } /*.................................................................................................................*/ /** Returns whether there is a splash banner*/ public boolean hasSplash(){ return true; } /*.................................................................................................................*/ /** returns the URL of the notices file for this module so that it can phone home and check for messages */ /*.................................................................................................................*/ public String getHomePhoneNumber(){ if (MesquiteTrunk.debugMode) return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/development/noticesAndUpdates/noticesDev.xml"; else if (!isPrerelease()) return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/master/noticesAndUpdates/notices.xml"; else return "https://raw.githubusercontent.com/MesquiteProject/Cartographer/development/noticesAndUpdates/noticesPrerelease.xml"; } /*.................................................................................................................*/ public String getPackageURL(){ return "http://mesquiteproject.org/packages/cartographer"; } /*.................................................................................................................*/ /** returns whether this module is a prerelease version. This returns "TRUE" here, forcing modules to override to claim they are not prerelease */ public boolean isPrerelease(){ return false; } /*.................................................................................................................*/ /** Returns version for a package of modules*/ public String getPackageVersion(){ return "1.50"; } /*.................................................................................................................*/ /** Returns version for a package of modules as an integer*/ public int getPackageVersionInt(){ return 150; } public String getPackageDateReleased(){ return "1 January 2017"; } /*.................................................................................................................*/ /** Returns build number for a package of modules as an integer*/ public int getPackageBuildNumber(){ return 30; } /* release dates: v1.0 5 May 2006 v1.2 19 September 2007 v1.3 8 June 2008 v1.31 1 January 2009 v1.4 19 August 2014 v1.41 29 August 2014 v1.50 1 January 2017 (build 30) * */ /*.................................................................................................................*/ public int getVersionOfFirstRelease(){ return 260; } } \ No newline at end of file