php IHDR w Q )Ba pHYs sRGB gAMA a IDATxMk\U s&uo,mD )Xw+e?tw.oWp;QHZnw`gaiJ9̟灙a=nl[ ʨ G;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ y H@E7j 1j+OFRg}ܫ;@Ea~ j`u'o> j- $_q?qS XzG'ay
files >> /usr/libexec/webmin/bacula-backup/ |
files >> //usr/libexec/webmin/bacula-backup/Hierarchy.java |
// Hierarchy // An AWT component for displaying a tree-like hierarchy, with each node // having an icon and a name. This hierarchy can be expanded or contracted // by the user. import java.awt.*; import java.util.Vector; public class Hierarchy extends BorderPanel implements CbScrollbarCallback { HierarchyNode root; // the root of the tree CbScrollbar sb; // scrollbar at right int width, height; // usable drawing area int sbwidth; // size of scrollbar HierarchyCallback callback; // who to call on open / close Image bim; // double-buffer image Font font = new Font("courier", Font.PLAIN, 12); FontMetrics fnm; // size of font used Graphics bg; // back-images graphics int top = 0; // top-most row displayed int count = 0; // total rows in the tree Insets in; // insets from border HierarchyNode sel; // selected node long last; // time of last mouse click static boolean broken_awt = System.getProperty("os.name"). startsWith("Windows"); // Create a new Hierarchy object with the given root Hierarchy(HierarchyNode r) { this(); root = r; } // Create a new Hierarchy object that calls back to the given object // when nodes are clicked on. Hierarchy(HierarchyNode r, HierarchyCallback c) { this(r); callback = c; } // Create an empty hierarchy object, with no callback Hierarchy() { super(3, Util.dark_edge_hi, Util.body_hi); // Create UI setLayout(null); sb = new CbScrollbar(CbScrollbar.VERTICAL, this); add(sb); } // Create an empty hierarchy object, set to report user actions to // the given object. Hierarchy(HierarchyCallback c) { this(); callback = c; } // redraw // Called by the using class when the tree passed to this object // changes, to force a redraw and resizing of the scrollbar void redraw() { if (fnm != null) { render(); paint(getGraphics()); compscroll(); } } // setRoot // Set the root node for this hierarchy void setRoot(HierarchyNode r) { root = r; redraw(); } // selected // Return the currently selected node, or null HierarchyNode selected() { return sel; } // select // Selected the given node void select(HierarchyNode s) { sel = s; } // force the use of some font public void setFont(Font f) { font = f; bim = null; repaint(); } // reshape // Called when this component gets resized public void reshape(int nx, int ny, int nw, int nh) { in = insets(); sbwidth = sb.minimumSize().width; width = nw-sbwidth - (in.left + in.right); height = nh - (in.top + in.bottom); sb.reshape(width+in.left, in.top, sbwidth, height); // force creation of a new backing images bim = null; repaint(); compscroll(); super.reshape(nx, ny, nw, nh); } // update // Called sometime after repaint() public void update(Graphics g) { render(); paint(g); } // paint // Blit the backing image to the front public void paint(Graphics g) { super.paint(g); if (bim == null) { // This is the first rendering bim = createImage(width, height); bg = bim.getGraphics(); bg.setFont(font); fnm = bg.getFontMetrics(); render(); compscroll(); } g.drawImage(bim, in.left, in.top, this); } // mouseDown // Called upon a mouseclick public boolean mouseDown(Event evt, int x, int y) { if (root == null) return false; // nothing to do HierarchyNode s = nodeat(root, x/16, (y/16)+top); if (s == null) { // Just deselect sel = null; repaint(); return true; } // Check for double-click boolean dc = false; if (evt.when-last < 500 && sel == s) dc = true; else last = evt.when; sel = s; if (dc && sel.ch != null) { // Open or close this node sel.open = !sel.open; if (callback != null) { // Notify callback, which MAY do something to change // the structure of the tree if (sel.open) callback.openNode(this, sel); else callback.closeNode(this, sel); } } else if (callback != null) { // Single click on a node or double-click on leaf node if (dc) callback.doubleNode(this, sel); else callback.clickNode(this, sel); } compscroll(); repaint(); return true; } public void moved(CbScrollbar s, int v) { moving(s, v); } public void moving(CbScrollbar s, int v) { top = sb.getValue(); compscroll(); repaint(); } // render // Draw the current tree view into the backing image private void render() { if (fnm != null) { int fh = fnm.getHeight(), // useful font metrics fa = fnm.getAscent(); bg.setColor(Util.light_bg); bg.fillRect(0, 0, width, height); if (root == null) return; // nothing to do bg.setColor(Util.text); recurse(root, 0, 0, fh, fa); } } // recurse // Render a node in the tree at the given location, maybe followed // by all it's children. Return the number of rows this node took // to display. private int recurse(HierarchyNode n, int x, int y, int fh, int fa) { int xx = x*16, yy = (y-top)*16; int len = 1; n.x = x; n.y = y; int tw = fnm.stringWidth(n.text); if (yy >= 0 && yy <= height) { // Draw this node if (n.im != null) bg.drawImage(n.im, xx, yy, this); if (sel == n) { // Select this node bg.setColor(Util.body); bg.fillRect(xx+17, yy+2, tw+2, 13); bg.setColor(Util.text); } bg.drawString(n.text, xx+18, yy+12); } if (n.ch != null && n.open && yy <= height) { // Mark this node bg.drawLine(xx+18, yy+14, xx+17+tw, yy+14); // Draw subnodes yy += 16; for(int i=0; i<n.ch.size() && yy<=height; i++) { int l=recurse((HierarchyNode)n.ch.elementAt(i), x+1, y+len, fh, fa); bg.drawLine(xx+7, yy+7, xx+15, yy+7); if (i == n.ch.size()-1) bg.drawLine(xx+7, yy, xx+7, yy+7); else bg.drawLine(xx+7, yy, xx+7,yy+(l*16)-1); len += l; yy += l*16; } } return len; } // compscroll // Re-compute scrollbar size private void compscroll() { if (fnm == null) return; int ct = root!=null ? count(root) : 1; int r = Math.min(ct, height/16 - 1); int c = ct - r; //sb.setValues(top, r==0?1:r, c<0?0:c); sb.setValues(top, r==0?1:r, ct); } // count // Returns the number of visible rows from a node private int count(HierarchyNode n) { int l = 1; if (n.open && n.ch != null) for(int i=0; i<n.ch.size(); i++) l += count((HierarchyNode)n.ch.elementAt(i)); return l; } // nodeat // Is the given node at the given position? If not, check its // children too. private HierarchyNode nodeat(HierarchyNode n, int x, int y) { if (y == n.y && x >= n.x) return n; if (n.ch == null || !n.open) return null; for(int i=0; i<n.ch.size(); i++) { HierarchyNode c = nodeat((HierarchyNode)n.ch.elementAt(i),x,y); if (c != null) return c; } return null; } } // HierarchyNode // One node in the tree displayed by the Hierarchy object. class HierarchyNode { boolean open; // is this node open? Image im; // icon for this node (assumed to be 16x16!) Vector ch; // sub-nodes of this one, or null String text; // name of this node int x, y; // row/column in list HierarchyNode() { } HierarchyNode(boolean o, Image i, Vector c, String t) { open = o; im = i; ch = c; text = t; } } // HierarchyCallback // Programmers using the Hierarchy class pass an object that implements the // HierarchyCallback interface to its constructor, to receive information // about user actions. interface HierarchyCallback { // openNode // Called when a node with children is opened void openNode(Hierarchy h, HierarchyNode n); // closeNode // Called when a node is closed void closeNode(Hierarchy h, HierarchyNode n); // clickNode // Called when the user clicks on a node void clickNode(Hierarchy h, HierarchyNode n); // doubleNode // Called when a user double-clicks on a node void doubleNode(Hierarchy h, HierarchyNode n); }y~or5J={Eeu磝Qk ᯘG{?+]ן?wM3X^歌>{7پK>on\jy Rg/=fOroNVv~Y+ NGuÝHWyw[eQʨSb> >}Gmx[o[<{Ϯ_qFvM IENDB`