summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/gui/controls/BlockProgressBar.java
blob: 94fd9ffdd2f8ad1f6a46ea0a35cfc1621a8fa2e4 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package gui.controls;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.openslx.thrifthelper.TransferStatusWrapper;

public class BlockProgressBar extends Canvas {

	private final Color white, blue, black;

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

	private final TransferStatusWrapper blocks = new TransferStatusWrapper(null);

	private boolean simpleMode = true;

	public BlockProgressBar(Composite parent) {
		super(parent, SWT.NO_BACKGROUND);
		setupListeners();
		white = getDisplay().getSystemColor(SWT.COLOR_WHITE);
		blue = getDisplay().getSystemColor(SWT.COLOR_BLUE);
		black = getDisplay().getSystemColor(SWT.COLOR_BLACK);
		// 0 = complete, 1 = missing, 2 = uploading, 3 = queued for copying, 4 = copying
		blockColors[0] = black;
		blockColors[1] = getDisplay().getSystemColor(SWT.COLOR_RED);
		blockColors[2] = getDisplay().getSystemColor(SWT.COLOR_YELLOW);
		blockColors[3] = blue;
		blockColors[4] = getDisplay().getSystemColor(SWT.COLOR_GREEN);
	}

	public void setStatus(byte[] blocks) {
		this.blocks.setBlocks(blocks);
		this.redraw();
	}

	private void setupListeners() {
		final BlockProgressBar me = this;
		// Paint listener
		this.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				me.draw(e);
			}
		});

		this.addMouseListener(new MouseListener() {

			@Override
			public void mouseUp(MouseEvent e) {
			}

			@Override
			public void mouseDown(MouseEvent e) {
			}

			@Override
			public void mouseDoubleClick(MouseEvent e) {
				me.toggleMode();
			}
		});
	}

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

	private void draw(PaintEvent e) {
		if (blocks.isEmpty()) {
			// No valid block data, draw white window
			e.gc.setBackground(white);
			e.gc.fillRectangle(e.x, e.y, e.width, e.height);
		} else if (simpleMode) {
			drawSimple(e);
		} else {
			drawDetailed(e);
		}
	}

	private void drawSimple(PaintEvent e) {
		final Rectangle a = this.getClientArea();
		final float width = a.width - 2;
		final float complete = blocks.getComplete();
		final float doneWidth = width * complete;
		e.gc.setBackground(blue);
		e.gc.fillRectangle(a.x, a.y, (int) doneWidth, a.height);
		e.gc.setBackground(white);
		e.gc.fillRectangle(a.x + (int) doneWidth, a.y, (int) (width - doneWidth), a.height);
		final String progress = (int) (complete * 100) + "%";
		Point textExtent = e.gc.textExtent(progress, SWT.DRAW_TRANSPARENT);
		final int textX = a.x + (a.width - textExtent.x) / 2;
		final int textY = a.y + (a.height - textExtent.y) / 2;
		e.gc.setForeground(white);
		e.gc.drawText(progress, textX - 1, textY - 1, true);
		e.gc.drawText(progress, textX + 1, textY + 1, true);
		e.gc.setForeground(black);
		e.gc.drawText(progress, textX, textY, true);
	}

	private void drawDetailed(PaintEvent e) {
		final int blockCount = blocks.getBlockCount();
		// Calculate display mode
		final Rectangle a = this.getClientArea();
		final float width = a.width - 2;
		float blockWidth = width / blockCount;
		int rows = 1;
		while (blockWidth * rows < 6 && a.height / rows > 8) {
			rows++;
		}
		blockWidth *= rows;
		final float blockHeight;
		final float blockHeightVisible;
		if (rows == 1) {
			blockHeightVisible = blockHeight = a.height;
		} else {
			blockHeight = (a.height + 2) / rows;
			blockHeightVisible = blockHeight - 2;
		}
		// Draw
		float x = a.x, y = a.y;
		for (byte block : blocks.getBlocks()) {
			if (block >= 0 && block < blockColors.length) {
				e.gc.setBackground(blockColors[block]);
			} else {
				e.gc.setBackground(white);
			}
			e.gc.fillRectangle((int) x, (int) y, (int) (x + blockWidth) - (int) x,
					(int) (y + blockHeightVisible) - (int) y);
			x += blockWidth;
			if (x + 0.5 > a.width) {
				e.gc.setBackground(white);
				e.gc.fillRectangle(a.x, (int) (y + blockHeightVisible), a.width, 2);
				x = a.x;
				y += blockHeight;
			}
		}
		// If we're multiline and have an odd number of blocks, there might be some remaining space - draw white
		if (x + 0.5 < a.width) {
			e.gc.setBackground(white);
			e.gc.fillRectangle((int) x, (int) y, (int) (x + blockWidth) - (int) x,
					(int) (y + blockHeightVisible) - (int) y);
		}
	}

}