1//*****************************************************************************
2//
3//	File:		ProgressBar.cpp
4//
5//	Written by:	David Ramsey and Daniel Switkin
6//
7//	Copyright 1999, Be Incorporated
8//
9//*****************************************************************************
10
11
12#include "ProgressBar.h"
13#include "PulseApp.h"
14
15
16ProgressBar::ProgressBar(BRect r, char *name) :	BView(r, name, B_FOLLOW_NONE,
17	B_WILL_DRAW)
18{
19	previous_value = current_value = 0;
20
21	// Create 20 segments
22	float height = (r.bottom - r.top) - 8;
23	for (int32 counter = 0; counter < 20; counter++) {
24		segments[counter].rect.Set(r.left + (counter * 7), r.top,
25			(r.left + (counter * 7) + 5), r.top + height);
26		segments[counter].rect.OffsetTo(BPoint((counter * 7) + 4, 4));
27	}
28	SetLowColor(255, 0, 0);
29	SetViewColor(B_TRANSPARENT_COLOR);
30}
31
32
33// New - real time updating of bar colors
34void
35ProgressBar::UpdateColors(int32 color, bool fade)
36{
37	unsigned char red = (color & 0xff000000) >> 24;
38	unsigned char green = (color & 0x00ff0000) >> 16;
39	unsigned char blue = (color & 0x0000ff00) >> 8;
40
41	if (fade) {
42		unsigned char red_base = red / 3;
43		unsigned char green_base = green / 3;
44		unsigned char blue_base = blue / 3;
45
46		for (int x = 0; x < 20; x++) {
47			segments[x].color.red = (uint8)(red_base + ((red - red_base)
48				* ((float)x / 19.0)));
49			segments[x].color.green = (uint8)(green_base
50				+ ((green - green_base) * ((float)x / 19.0)));
51			segments[x].color.blue = (uint8)(blue_base + ((blue - blue_base)
52				* ((float)x / 19.0)));
53			segments[x].color.alpha = 0xff;
54		}
55	} else {
56		for (int x = 0; x < 20; x++) {
57			segments[x].color.red = red;
58			segments[x].color.green = green;
59			segments[x].color.blue = blue;
60			segments[x].color.alpha = 0xff;
61		}
62	}
63	Render(true);
64}
65
66
67void
68ProgressBar::AttachedToWindow()
69{
70	Prefs *prefs = ((PulseApp *)be_app)->fPrefs;
71	UpdateColors(prefs->normal_bar_color, prefs->normal_fade_colors);
72}
73
74
75void
76ProgressBar::MouseDown(BPoint point)
77{
78	point = ConvertToParent(point);
79	Parent()->MouseDown(point);
80}
81
82
83void
84ProgressBar::Set(int32 value)
85{
86	// How many segments to light up
87	current_value = (int32)(value / 4.9);
88	if (current_value > 20)
89		current_value = 20;
90
91	Render(false);
92}
93
94
95// Draws the progress bar. If "all" is true the entire bar is redrawn rather
96// than just the part that changed.
97void
98ProgressBar::Render(bool all)
99{
100	if (all) {
101		// Black border
102		BRect bounds = Bounds();
103		bounds.InsetBy(2, 2);
104		SetHighColor(0, 0, 0);
105		StrokeRect(bounds);
106		bounds.InsetBy(1, 1);
107		StrokeRect(bounds);
108
109		// Black dividers
110		float left = bounds.left;
111		BPoint start, end;
112		for (int x = 0; x < 19; x++) {
113			left += 7;
114			start.Set(left, bounds.top);
115			end.Set(left, bounds.bottom);
116			StrokeLine(start, end);
117		}
118
119		for (int x = 0; x < current_value; x++) {
120			SetHighColor(segments[x].color.red, segments[x].color.green,
121				segments[x].color.blue);
122			FillRect(segments[x].rect);
123		}
124
125		SetHighColor(75, 75, 75);
126		if (current_value < 20) {
127			for (int x = 19; x >= current_value; x--) {
128				FillRect(segments[x].rect);
129			}
130		}
131	} else if (current_value > previous_value) {
132		for (int x = previous_value; x < current_value; x++) {
133			SetHighColor(segments[x].color.red, segments[x].color.green,
134				segments[x].color.blue);
135			FillRect(segments[x].rect);
136		}
137	} else if (current_value < previous_value) {
138		SetHighColor(75, 75, 75);
139		for (int x = previous_value - 1; x >= current_value; x--) {
140			FillRect(segments[x].rect);
141		}
142		// Special case to make sure the lowest light gets turned off
143		if (current_value == 0) FillRect(segments[0].rect);
144	}
145
146	Sync();
147	previous_value = current_value;
148}
149
150
151void
152ProgressBar::Draw(BRect rect)
153{
154	// Add bevels
155	SetHighColor(dkgray, dkgray, dkgray);
156	BRect frame = Bounds();
157	StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
158	StrokeLine(BPoint(frame.left, frame.top + 1), BPoint(frame.right,
159		frame.top + 1));
160	StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.left,
161		frame.bottom));
162	StrokeLine(BPoint(frame.left + 1, frame.top),
163		BPoint(frame.left + 1, frame.bottom));
164
165	SetHighColor(ltgray, ltgray, ltgray);
166	StrokeLine(BPoint(frame.right-1, frame.top + 2),
167		BPoint(frame.right - 1, frame.bottom));
168	StrokeLine(BPoint(frame.right, frame.top + 1),
169		BPoint(frame.right, frame.bottom));
170	StrokeLine(BPoint(frame.left+1, frame.bottom - 1),
171		BPoint(frame.right - 1, frame.bottom - 1));
172	StrokeLine(BPoint(frame.left, frame.bottom),
173		BPoint(frame.right, frame.bottom));
174
175	Render(true);
176}
177