summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/BlockProgressBar.java
blob: 4d5c0add47922ae59a060b5486db271092768952 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package org.openslx.dozmod.gui.control;

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

import javax.swing.JPanel;

import org.openslx.thrifthelper.TransferStatusWrapper;

@SuppressWarnings("serial")
public class BlockProgressBar extends JPanel {

	private final Color[] blockColors = new Color[5];

	private final TransferStatusWrapper blocks = new TransferStatusWrapper(null);

	private boolean simpleMode = true;

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

	public void setStatus(byte[] blocks) {
		this.blocks.setBlocks(blocks);
		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) {
		final float width = getWidth();
		final int height = getHeight();
		final float complete = blocks.getComplete();
		final float doneWidth = width * complete;
		final Rectangle doneRect = new Rectangle(0, 0, (int) doneWidth, height);
		final Rectangle remainingRect = new Rectangle((int) doneWidth, 0, (int) (width - doneWidth), height);
		g.setColor(Color.BLUE);
		g.fillRect(doneRect.x, doneRect.y, doneRect.width, doneRect.height);
		g.setColor(Color.WHITE);
		g.fillRect(remainingRect.x, remainingRect.y, remainingRect.width, remainingRect.height);
		final String progress = (int) (complete * 100) + "%";
		Rectangle2D textExtent = g.getFontMetrics().getStringBounds(progress, g);
		final int textX = (int) ((width - textExtent.getWidth()) / 2);
		final int textY = (int) ((height - textExtent.getHeight()) / 2);
		g.setColor(Color.WHITE);
		g.setClip(doneRect.x, doneRect.y, doneRect.width, doneRect.height);
		g.drawString(progress, textX, textY);
		g.setColor(Color.BLACK);
		g.setClip(remainingRect.x, remainingRect.y, remainingRect.width, remainingRect.height);
		g.drawString(progress, 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;
		for (byte block : blocks.getBlocks()) {
			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;
				g.fillRect((int) x, (int) y, boxWidth > 1 ? boxWidth : 1, boxHeight > 1 ? boxHeight : 1);
			}
			x = toX;
			if (x + 0.5 > width) {
				x = 0;
				y += blockHeight;
			}
		}
	}

}