summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/BlockProgressBar.java
blob: c7e0172f7a55fa4da283878040e0d69754d7a5c8 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                                       
 

                         
                           
                               




                                   
 
                                                     
                                  
                                                      
 
                                              
 




                                                                          
                                                         
        
                                                                                          

                                                                                     

                                                                                                     


                                          
                                                      

                                            
 

                                                
                                                                  
                                 
                                                                                                             




                                              
                                                       
                                              

         


                                                                        
                                  



                                                 
                                                          
                                 



                                                                





                                         
                                  

         

                                                

                                                                 

                                                                  
                                        
                                      
                        
                                        


                 
                                             



                                                                                               
                                             
                                               


                                                                                            
                                         
                                       
                                                    




                                                                         
                                        


                                                                                               


                                                              
                                                                                


                                                           
                                                                   



                                                                           
                                                                   
                 

         
                                               

                                                              

                                                   

                                                      
                                                                            





                                               
                                                                  
                        
                                                          


                                                             


                                                          


                                                     
                                                   
                                                                       
                                                               

                                                                                               




                                                                                                                                 
                         
                                

                                              


                                                 

         



                                                       
 
package org.openslx.dozmod.gui.control;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

import org.openslx.dozmod.filetransfer.TransferEvent;
import org.openslx.dozmod.gui.Gui;
import org.openslx.thrifthelper.TransferStatusWrapper;

public class BlockProgressBar extends JPanel {

	/**
	 * Version for serialization.
	 */
	private static final long serialVersionUID = 3530794778387334915L;

	private final Color[] blockColors = new Color[6];
	
	private static final Color potentialCompleteColor = new Color(215, 230, 255, 255);

	private final TransferStatusWrapper blocks = new TransferStatusWrapper(null);
	
	private final TransferStatusWrapper.Progress progress = new TransferStatusWrapper.Progress();

	private boolean simpleMode = true;

	private boolean showEstimatedComplete = false;
	
	private int locallyHashedBlockCount;

	public BlockProgressBar(byte[] blocks) {
		super();
		setPreferredSize(Gui.getScaledDimension(100, 32));
		setupListeners();
		// 0 = complete, 1 = missing, 2 = uploading, 3 = queued for copying, 4 = copying, 5 = hashing
		blockColors[0] = Color.BLACK;
		blockColors[1] = Color.RED;
		blockColors[2] = Color.YELLOW;
		blockColors[3] = Color.BLUE;
		blockColors[4] = Color.GREEN;
		blockColors[5] = Color.YELLOW.darker();
		this.blocks.setBlocks(blocks);
	}

	public void setStatus(TransferEvent event) {
		this.blocks.setBlocks(event.progress);
		this.locallyHashedBlockCount = event.locallyHashedCount;
		this.repaint(100);
	}

	private void setupListeners() {
		final BlockProgressBar me = this;
		this.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					me.toggleMode();
				}
			}
		});
	}

	private void toggleMode() {
		simpleMode = !simpleMode;
		this.repaint(100);
	}

	@Override
	public void paintComponent(Graphics g) {
		if (blocks.isEmpty()) {
			// No valid block data, draw white window
			g.setColor(Color.WHITE);
			g.fillRect(0, 0, getWidth(), getHeight());
		} else if (simpleMode) {
			drawSimple(g);
		} else {
			drawDetailed(g);
		}
	}

	private void drawSimple(Graphics g) {
		if (g instanceof Graphics2D) {
			((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
					RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		}
		final int width = getWidth();
		final int height = getHeight();
		blocks.getCompleteEx(progress);
		final int doneWidth = (int) ((float) width * progress.done);
		final int potentialWidth = (int) ((float) width * progress.potentiallyDone);
		int sumWidth = doneWidth;
		g.setColor(Color.BLUE);
		g.fillRect(0, 0, doneWidth, height);
		if (showEstimatedComplete) {
			g.setColor(potentialCompleteColor);
			g.fillRect(doneWidth, 0, potentialWidth, height);
			sumWidth += potentialWidth;
		}
		g.setColor(Color.WHITE);
		g.fillRect(sumWidth, 0, width - sumWidth, height);
		final String percentDisplay = (int) (progress.done * 100) + "%";
		Rectangle2D textExtent = g.getFontMetrics().getStringBounds(percentDisplay, g);
		final double tw = textExtent.getWidth();
		final int textX = (int) ((width - tw) / 2);
		final int textXEnd = (int) ((width + tw) / 2);
		final int textY = (int) ((height + textExtent.getHeight()) / 2);
		if (doneWidth >= textX) {
			g.setColor(Color.WHITE);
			g.setClip(0, 0, doneWidth, height);
			g.drawString(percentDisplay, textX, textY);
		}
		if (doneWidth <= textXEnd) {
			g.setColor(Color.BLACK);
			g.setClip(doneWidth, 0, width - doneWidth, height);
			g.drawString(percentDisplay, textX, textY);
		}
	}

	private void drawDetailed(Graphics g) {
		final int blockCount = blocks.getBlockCount();
		// Calculate display mode
		final int height = getHeight();
		final float width = getWidth() - 2;
		float blockWidth = width / blockCount;
		int rows = 1;
		while (blockWidth * rows < 6 && (float) height / rows > 7) {
			rows++;
		}
		blockWidth *= rows;
		final float blockHeight;
		final float blockHeightVisible;
		if (rows == 1) {
			blockHeightVisible = blockHeight = height;
		} else {
			blockHeight = (height + 2) / rows;
			blockHeightVisible = blockHeight - 2;
		}
		// Draw
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, getWidth(), getHeight());
		float x = 0, y = 0;
		byte[] ba = blocks.getBlocks();
		for (int i = 0; i < ba.length; ++i) {
			byte block = ba[i];
			float toX = x + blockWidth;
			if (block >= 0 && block < blockColors.length) {
				g.setColor(blockColors[block]);
				final int boxWidth = ((int) toX) - ((int) x) - 1;
				final int boxHeight = (int) (y + blockHeightVisible) - (int) y;
				if (i < locallyHashedBlockCount) {
					g.fillRect((int) x, (int) y, boxWidth > 1 ? boxWidth : 1, boxHeight > 1 ? boxHeight : 1);
				} else {
					g.drawRect((int) x, (int) y, boxWidth > 1 ? boxWidth : 1, boxHeight > 1 ? boxHeight : 1);
				}
			}
			x = toX;
			if (x + 0.5 > width) {
				x = 0;
				y += blockHeight;
			}
		}
	}

	public void showOptimisticComplete(boolean b) {
		this.showEstimatedComplete  = b;
	}

}